Python 如何仅将此网站HTML表的第一列和href链接刮入数据框?

Python 如何仅将此网站HTML表的第一列和href链接刮入数据框?,python,html,pandas,web-scraping,Python,Html,Pandas,Web Scraping,。我想 >刮擦< /强>中间的那个表,只需要第一列(公司名称)加上它的HREF链接。< /P> 例如,在这里,我只想刮取第一个之间的所有数据,忽略其余三个值。然后用公司名称创建一列(本例中为1-800-FLOWERS.COM),然后用href链接创建第二列(/company/1-800-flowerscom) 到目前为止我所做的: url = "http://www.annualreports.com/Companies?search=" html = request.ur

。我想<强> >刮擦< /强>中间的那个表,只需要第一列(公司名称)加上它的HREF链接。< /P> 例如,在这里,我只想刮取第一个
之间的所有数据,忽略其余三个
值。然后用公司名称创建一列(本例中为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)
这将成功地以以下格式提取所有
标记:

现在,填充df列的最有效方法是将第二个嵌套循环更改为步骤4,并接受1个值,然后忽略接下来的3个值吗?这对我来说似乎真的很复杂,有没有更好的方法可以让我直接从源头上完成这一切?也就是说,从所有
中只提取第一个
值,然后将公司名称和href值分成两个不同的列(对于整个表)

您可以使用它限制到第一列(
td
)。由于节点同时具有感兴趣的
href
和文本,您可以使用列表理解中的元组从同一节点检索这两个元素,然后依靠末尾的熊猫来处理列。我正在使用bs4.7.1。不确定从哪个版本开始支持此功能,但由于所做的改进,您确实希望使用最新的bs4

import requests
import pandas as pd
from bs4 import BeautifulSoup as bs

r = requests.get('http://www.annualreports.com/Companies?search=')
soup = bs(r.content, 'lxml')
df = pd.DataFrame([(i.text, 'http://www.annualreports.com' + i['href']) for i in soup.select('tbody td:nth-of-type(1) a')], columns = ['Company','Link'])
print(df)

一些解释:

soup.select('tbody td:nth-of-type(1) a')
选择第一列(
td
)中的所有子
a
标记<代码>t正文用于确保使用正确的表格。
tbody、td
a
是并基于标记进行选择,而中间的空格是,这意味着右侧要匹配的元素是左侧要匹配的元素的子元素

select
返回一个列表

列表理解

[(i.text, 'http://www.annualreports.com' + i['href']) for i in soup.select('tbody td:nth-of-type(1) a')]
可以改写为:

for i in soup.select('tbody td:nth-of-type(1) a'):
    (i.text, 'http://www.annualreports.com' + i['href']) #tuple that is then added to a final list
当您在
返回的列表中迭代每个
标记时,选择
;当前节点(
a
标记)既有标题,也有其
.text
属性,并将
href
作为属性。可以访问属性值,如图所示。
'http://www.annualreports.com“
添加前缀以使链接完整(否则它们是相对的,并且缺少协议和域)

该列表被传递给pandas,其中元组列表(根据示例称之为
The_list
)被解压到两列中。
pd.DataFrame
columns
参数用于命名数据框中的列

df = pd.DataFrame(the_list , columns = ['Company','Link'])  # the_list being the result of the list comprehension

你能再详细解释一下最后一行吗?我知道它在做什么,但从左到右逐字逐句地说,这对我来说并没有多大意义。也非常感谢你的代码,它比我想做的要简单得多;我还没有听说过第N种类型,之前我为你添加了更多信息。非常感谢!!!这是有道理的,尽管我仍然不确定我是否能够独自写下这样的东西:(