Website in question。我想要<强> >刮擦< /强>中间的那个表,只需要第一列(公司名称)加上它的HREF链接。
例如,在这里,我只想刮取第一个<td> </td>
之间的所有数据,忽略其余三个<td>
值。然后用公司名称创建一列(本例中为1-800-FLOWERS.COM),然后用href链接创建第二列(/company/1-800-flowerscom)
到目前为止我所做的:
url = "http://www.annualreports.com/Companies?search="
html = request.urlopen(url).read().decode('utf8')
soup = BeautifulSoup(html, "html.parser")
df = pd.DataFrame(columns=['Company', 'Href'])
tables = soup.findChildren('table')
my_table = tables[0]
rows = my_table.findChildren(['th', 'tr'])
for row in rows:
cells = row.findChildren('td')
for cell in cells:
value = cell.string
print(value)
这将成功地以以下格式提取所有标签<td>
:
现在,填充df列的最有效方法是将第二个嵌套循环更改为步骤4,并接受1个值,然后忽略接下来的3个值吗?这对我来说似乎真的很复杂,有没有更好的方法可以让我直接从源头上完成这一切?也就是说,仅从所有<tr>
中提取第一个<td>
值,然后将公司名称和href值分成两个不同的列(对于整个表)
您可以使用nth-of-type限制到第一列(
td
)。由于节点同时具有感兴趣的href
和文本,您可以使用列表理解中的元组从同一节点检索这两个元素,然后依靠末尾的熊猫来处理列。我正在使用bs4.7.1。不确定从哪个版本开始支持此功能,但由于所做的改进,您确实希望使用最新的bs4一些解释:
选择第一列(}是type selectors并基于标记进行选择,而两者之间的空格是descendant combinators,这意味着右侧要匹配的元素是左侧要匹配的元素的子元素
td
)中的所有子a
标记tbody
用于确保使用正确的表。tbody,td
和{select
返回一个列表列表理解
可以改写为:
迭代
select
返回的列表中的每个a
标记时;当前节点(a
标记)既有标题,也有其.text
属性,并将href
作为属性。可以访问属性值,如图所示。添加'http://www.annualreports.com'
前缀是为了使链接完整(否则它们是相对的,缺乏协议和域)该列表被传递给pandas,其中元组列表(根据示例称之为
the_list
)被解压到两列中。pd.DataFrame
的columns
参数用于命名数据帧中的列相关问题 更多 >
编程相关推荐