python - 如何从表格中获取所有 tr 元素并单击链接?
问题描述
我试图弄清楚如何打印表格中的所有 tr 元素,但我不能让它正常工作。
这是我正在使用的链接。
https://en.wikipedia.org/wiki/List_of_current_members_of_the_United_States_Senate
这是我的代码。
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'
. 另外,我想知道是否有一种方法可以点击参议员的链接,就像'Richard Shelby'
我这样:
https://en.wikipedia.org/wiki/Richard_Shelby
从每个链接中,我想获取'Assumed office'
. 在这种情况下,值为:'January 3, 2018'
。所以,最终,我想结束这个:
Richard Shelby May 6, 1934 (age 84) Lawyer U.S. House
Alabama Senate January 3, 1987 2022
Assumed office: January 3, 2018
我现在能得到的只是打印出来的每个参议员的名字。
解决方案
为了定位“Senators”表,可以先找到对应的“Senators” label
,然后得到以下第一个table
元素:
soup.find(id='Senators').find_next("table")
现在,为了逐行获取数据,您必须考虑具有跨越多行的“行跨度”的单元格。您可以按照我在 <tr> 有 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 对象允许您跨请求保留某些参数。它还在从 Session 实例发出的所有请求中保留 cookie,并将使用 urllib3 的连接池。因此,如果您向同一主机发出多个请求,则会重用底层 TCP 连接,从而显着提高性能
还有另一种方法可以解析表格数据 -.read_html()
从pandas
. 你可以这样做:
import pandas as pd
df = pd.read_html(str(senators_table))[0]
print(df.head())
将所需的表作为数据框。
推荐阅读
- python - 单击 Windows 应用程序并使用 pywinauto 输入文本
- c++ - 共享内存数组中两个单元格的差异(并发)
- javascript - 如何在 Node js 中同步使用串口?
- wcf - Web.config 未在 IIS 中用于 WCF
- php - .ttf 文件不起作用
- python - QtWebView 哪个版本的 HTML?
- javascript - 当字体名称有空格时如何使用 JQuery 设置 CSS 字体系列
- google-bigquery - google bigquery 提取压缩现在不起作用
- javascript - 如何在html中获取js返回值请在屏幕截图中找到以下代码
- java - 如果我们没有为对象创建引用变量,如何关闭扫描程序类,从而避免资源泄漏警告消息