我试图弄清楚如何从表中打印所有tr元素,但是我不能完全正常工作。
这是我正在使用的链接。
https://en.wikipedia.org/wiki/List_of_current_members_of_the_United_States_Senate
这是我的代码。
insert_many
我正在尝试打印名为import requests
from bs4 import BeautifulSoup
link = "https://en.wikipedia.org/wiki/List_of_current_members_of_the_United_States_Senate"
html = requests.get(link).text
# If you do not want to use requests then you can use the following code below
# with urllib (the snippet above). It should not cause any issue."""
soup = BeautifulSoup(html, "lxml")
res = soup.findAll("span", {"class": "fn"})
for r in res:
print("Name: " + r.find('a').text)
table_body=soup.find('senators')
rows = table_body.find_all('tr')
for row in rows:
cols=row.find_all('td')
cols=[x.text.strip() for x in cols]
print(cols)
的表中的所有tr
元素。另外,我想知道是否有一种方法可以点击参议员的链接,例如'senators'
可以带我到这里:
https://en.wikipedia.org/wiki/Richard_Shelby
我想从每个链接获取'Richard Shelby'
下的数据。在这种情况下,值为:'Assumed office'
。因此,最终,我想结束这一点:
'January 3, 2018'
我现在能得到的是打印出每个参议员的名字。
答案 0 :(得分:1)
为了找到“ Senators”表,您可以先找到相应的“ Senators” label
,然后再找到get the first following table
element:
soup.find(id='Senators').find_next("table")
现在,为了逐行获取数据,您将不得不考虑具有“行跨度”的单元格,这些单元格跨多行。您可以遵循What should I do when <tr> has rowspan中建议的方法,也可以遵循我在下面提供的实现方式(不理想,但可以使用)。
import copy
import requests
from bs4 import BeautifulSoup
link = "https://en.wikipedia.org/wiki/List_of_current_members_of_the_United_States_Senate"
with requests.Session() as session:
html = session.get(link).text
soup = BeautifulSoup(html, "lxml")
senators_table = soup.find(id='Senators').find_next("table")
headers = [td.get_text(strip=True) for td in senators_table.tr('th')]
rows = senators_table.find_all('tr')
# pre-process table to account for rowspan, TODO: extract into a function
for row_index, tr in enumerate(rows):
for cell_index, td in enumerate(tr('td')):
if 'rowspan' in td.attrs:
rowspan = int(td['rowspan'])
del td.attrs['rowspan']
# insert same td into subsequent rows
for index in range(row_index + 1, row_index + rowspan):
try:
rows[index]('td')[cell_index].insert_after(copy.copy(td))
except IndexError:
continue
# extracting the desired data
rows = senators_table.find_all('tr')[1:]
for row in rows:
cells = [td.get_text(strip=True) for td in row('td')]
print(dict(zip(headers, cells)))
然后,如果需要,请遵循指向参议员“个人资料”页面的链接,您首先需要将链接从适当的单元格中提取出来,然后使用session.get()
“导航”到该链接,大致如下:
senator_link = row.find_all('td')[3].a['href']
senator_link = urljoin(link, senator_link)
response = session.get(senator_link)
soup = BeautifulSoup(response.content, "lxml")
# TODO: parse
其中urljoin
的导入方式为:
from urllib.parse import urljoin
仅供参考,在这里使用requests.Session()
的原因之一是优化向同一主机发出的请求:
Session对象允许您在请求中保留某些参数。它还会在来自会话实例的所有请求中保留cookie,并将使用urllib3的连接池。因此,如果您要向同一主机发出多个请求,则基础TCP连接将被重用,这可以显着提高性能
还有另一种获取表格数据的方法-pandas
中的.read_html()
。您可以这样做:
import pandas as pd
df = pd.read_html(str(senators_table))[0]
print(df.head())
获取所需的表作为数据框。