使用beautifulsoup 和selenium webdriver 需要帮助Web 抓取表
Posted
技术标签:
【中文标题】使用beautifulsoup 和selenium webdriver 需要帮助Web 抓取表【英文标题】:Need help web scraping table with beautifulsoup and selenium webdriver 【发布时间】:2020-08-14 08:18:57 【问题描述】:所以我正在努力尝试对https://data.bls.gov/cgi-bin/surveymost?bls 进行网络抓取,并能够弄清楚如何通过点击进行网络爬网以到达一张桌子。
我正在练习的选择是在您选择与“就业成本指数(ECI)平民(未调整)-CIU1010000000000A”相关的复选框后,然后选择“检索数据”。
处理完这两个后,表格将显示。这是我要抓取的表格。
以下是我目前拥有的代码。
请注意,您必须将自己的浏览器驱动程序路径放在我放置的位置。
from bs4 import BeautifulSoup
from urllib.request import urlopen
import pandas as pd
import numpy as np
import requests
import lxml.html as lh
from selenium import webdriver
url = "https://data.bls.gov/cgi-bin/surveymost?bls"
ChromeSource = r"<browser driver>"
# Open up a Chrome browser and navigate to web page.
options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
options.add_argument('--incognito')
options.add_argument('--headless') # will run without opening browser.
driver = webdriver.Chrome(ChromeSource, chrome_options=options)
driver.get(url)
driver.find_element_by_xpath("//input[@type='checkbox' and @value = 'CIU1010000000000A']").click()
driver.find_element_by_xpath("//input[@type='Submit' and @value = 'Retrieve data']").click()
i = 2
def myTEST(i):
xpath = '//*[@id="col' + str(i) + '"]'
TEST = driver.find_elements_by_xpath(xpath)
num_page_items = len(TEST)
for i in range(num_page_items):
print(TEST[i].text)
myTEST(i)
# Clean up (close browser once completed task).
driver.close()
现在这只是查看标题。我也想获得表格内容。
如果我让 i = 0,它会产生“年”。 i = 1,它产生“期间”。但是,如果我选择 i = 2,我会得到两个变量,它们对于“估计值”和“标准误差”具有相同的 col2 id。
我试图想办法解决这个问题,但似乎无法得到我研究过的任何东西。
本质上,最好从我完成单击并位于感兴趣的表处开始,然后查看标题的 xpath 并为所有 sub 拉入文本。
<tr> == $0
<th id="col0"> Year </th>
<th id="col1"> Period </th>
<th id="col2">Estimated Value</th>
<th id="col2">Standard Error</th>
<tr>
我不知道该怎么做。我还尝试遍历 i 但显然与两个标题文本共享会导致问题。
一旦我能够获得标题,我就想获得内容。如果我走在正确的道路上,是否想得太多,或者是否有更简单的方法来完成所有这些,我可以让你了解一下。我正在学习,这是我第一次尝试使用 selenium 库进行点击。我只是想让它工作,这样我就可以在不同的桌子上再试一次,并使其尽可能自动化或可重复使用(通过调整)。
【问题讨论】:
刮还是刮? [Edited] Scraping* 感谢您发现这一点,通过拼写错误并不是我寻求帮助的真正重点。 :) 【参考方案1】:其实你不需要selenium
,你可以只跟踪POST
Form data
,并在你的POST
请求中应用它。
然后您可以使用Pandas
轻松加载表格。
import requests
import pandas as pd
data =
"series_id": "CIU1010000000000A",
"survey": "bls"
def main(url):
r = requests.post(url, data=data)
df = pd.read_html(r.content)[1]
print(df)
main("https://data.bls.gov/cgi-bin/surveymost")
解释:
打开site。 选择Employment Cost Index (ECI) Civilian (Unadjusted) - CIU1010000000000A
现在您必须打开浏览器Developer Tools 并导航到Network Monitor
部分。 etc 按 Ctrl + Shift + E (Command + Option + E 在 Mac 上)。
现在您会发现 POST
请求已完成。
导航到Params
选项卡。
现在您可以发出POST
请求。并且由于Table
是在HTML
源中提供的,并且它不是通过javascript
加载的,因此您可以在bs4
中解析它或使用pandas.read_html() 以良好的格式阅读它
注意:只要不是通过JavaScript
加载的表格,您就可以读取表格。否则您可以尝试跟踪XHR
请求(检查以前的answer),或者您可以使用selenium
或requests_html
来渲染JS
,因为requests
是一个无法渲染它的HTTP
库为你。
【讨论】:
哇!这不仅有效,而且它是如此动态,以至于它也可以与其他表格一起使用!我肯定是想多了,但话又说回来,我不完全理解这是如何工作的。我需要再消化一下才能弄清楚那部分,但非常感谢! @AndrewHicks 欢迎您,如果您发现任何不清楚的地方,请告诉我,以便我解释 是的......你知道任何可能涵盖你在这里所做的概念的“文献”吗?我的背景是分析(python、r 和 sql)而不是 html。每个网站的 data = 中的信息是否不同?我可以在 yahoo Finance 或任何其他有表格的页面上使用它吗?我认为需要进行一些调整(除了 url 和数据变量,比如你在 series_id 和调查中输入的变量。再次感谢。我绝对想学习这个。 @AndrewHicks 让我在答案中解释一下。坚持 所以跟进。首先,看起来这种方法并不适合所有网站,目前还可以。其次,我想调整代码,使其不仅仅是从 2010-2020 年开始,而是从 1939-2020 年开始。在网站上,这需要从顶部的下拉菜单中选择 1939,然后选择“go”。我试着按照你的方式去做,但它只会出错。有任何想法吗?数据 =“from_year”:“1939”,&“to_year”:“2020”。另外,所以我认为 params 字段存在于 FireFox 中。你知道Chrome中是否有类似的东西吗?以上是关于使用beautifulsoup 和selenium webdriver 需要帮助Web 抓取表的主要内容,如果未能解决你的问题,请参考以下文章
使用 Selenium 和 Beautifulsoup 解析 Airdna 地图悬停在文本上
如何在 python 中使用 Selenium 和 Beautifulsoup 解析网站? [关闭]
使用 Selenium 时不完整的 BeautifulSoup 刮擦
Selenium/BeautifulSoup - Python - 循环多个页面