尝试用 Python 的 Beautifulsoup 和 Selenium 抓取 Table
Trying to Scrape Table with Python's Beautifulsoup & Selenium
如标题所示,我正在尝试同时使用 Beautifulsoup 和 Selenium 抓取 table。我知道我很可能不需要这两个库,但是我想尝试使用 Selenium 的 xpathselectors 是否有帮助,不幸的是他们没有。
可在此处找到该网站:
https://app.capitoltrades.com/politician/491
我想做的是刮掉底部 'Trades' 下的 table
这是截图
一旦我可以获取 table,我将收集 table 行内的 td 数据。
例如,我想要 'Publication Date' 下的“29/Dec/2021”。不幸的是,我没能走到这一步,因为我抓不到 table.
这是我的代码:
from bs4 import BeautifulSoup
import requests
from selenium import webdriver
url = 'https://app.capitoltrades.com/politician/491'
resp = requests.get(url)
#soup = BeautifulSoup(resp.text, "html5lib")
soup = BeautifulSoup(resp.text, 'lxml')
table = soup.find("table", {"class": "p-datatable-table ng-star-
inserted"}).findAll('tr')
print(table)
这会产生错误消息“AttributeError: 'NoneType' object 没有属性 'findAll'
使用 'soup.findAll' 也不起作用。
如果我尝试使用 Selenium 的 xpathselector 路由 ...
DRIVER_PATH = '/Users/myname/Downloads/capitol-trades/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.implicitly_wait(1000)
driver.get('https://app.capitoltrades.com/politician/491')
table = driver.find_element_by_xpath("//*[@id='pr_id_2']/div/table").text
print(table)
Chrome 继续打开,我的 Jupyter notebook 中没有打印任何内容(可能是因为 table 元素[?] 中没有直接的文本)
我希望能够使用 Beautifulsoup 获取 table 元素,但欢迎所有答案。我很感激你能为我提供的任何帮助。
根据您的 Selenium 代码:您需要等待。
这个
driver.find_element_by_xpath("//*[@id='pr_id_2']/div/table")
command returns 刚创建的 web 元素,即已经存在,但仍未完全呈现。
这应该会更好:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
DRIVER_PATH = '/Users/myname/Downloads/capitol-trades/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
wait = WebDriverWait(driver, 20)
driver.get('https://app.capitoltrades.com/politician/491')
table = wait.until(EC.visibility_of_element_located((By.XPATH, "//*[@id='pr_id_2']//tr[@class='p-selectable-row ng-star-inserted']"))).text
print(table)
根据您的 BS4 代码,您似乎使用了错误的定位器。
这个:
table = soup.find("table", {"class": "p-datatable-table ng-star-inserted"})
看起来更好(你的 class 名字中有多余的空格)。
上面的行 returns 5 个元素。
所以这应该有效:
table = soup.find("table", {"class": "p-datatable-table ng-star-inserted"}).findAll('tr')
该站点有一个很容易被攻击的后端api:
import requests
import pandas as pd
url = 'https://api.capitoltrades.com/senators/trades/491/false?pageSize=20&pageNumber=1'
resp = requests.get(url).json()
df = pd.DataFrame(resp)
df.to_csv('naughty_nancy_trades.csv',index=False)
print('Saved to naughty_nancy_trades.csv ')
要查看所有数据的来源,请打开浏览器的开发人员工具 - 网络 - fetch/XHR 并重新加载页面,你会看到它们被触发。我抓取了其中一个网络调用,该页面上的所有数据还有其他网络调用
如标题所示,我正在尝试同时使用 Beautifulsoup 和 Selenium 抓取 table。我知道我很可能不需要这两个库,但是我想尝试使用 Selenium 的 xpathselectors 是否有帮助,不幸的是他们没有。
可在此处找到该网站:
https://app.capitoltrades.com/politician/491
我想做的是刮掉底部 'Trades' 下的 table
这是截图
一旦我可以获取 table,我将收集 table 行内的 td 数据。
例如,我想要 'Publication Date' 下的“29/Dec/2021”。不幸的是,我没能走到这一步,因为我抓不到 table.
这是我的代码:
from bs4 import BeautifulSoup
import requests
from selenium import webdriver
url = 'https://app.capitoltrades.com/politician/491'
resp = requests.get(url)
#soup = BeautifulSoup(resp.text, "html5lib")
soup = BeautifulSoup(resp.text, 'lxml')
table = soup.find("table", {"class": "p-datatable-table ng-star-
inserted"}).findAll('tr')
print(table)
这会产生错误消息“AttributeError: 'NoneType' object 没有属性 'findAll'
使用 'soup.findAll' 也不起作用。
如果我尝试使用 Selenium 的 xpathselector 路由 ...
DRIVER_PATH = '/Users/myname/Downloads/capitol-trades/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.implicitly_wait(1000)
driver.get('https://app.capitoltrades.com/politician/491')
table = driver.find_element_by_xpath("//*[@id='pr_id_2']/div/table").text
print(table)
Chrome 继续打开,我的 Jupyter notebook 中没有打印任何内容(可能是因为 table 元素[?] 中没有直接的文本)
我希望能够使用 Beautifulsoup 获取 table 元素,但欢迎所有答案。我很感激你能为我提供的任何帮助。
根据您的 Selenium 代码:您需要等待。
这个
driver.find_element_by_xpath("//*[@id='pr_id_2']/div/table")
command returns 刚创建的 web 元素,即已经存在,但仍未完全呈现。
这应该会更好:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
DRIVER_PATH = '/Users/myname/Downloads/capitol-trades/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
wait = WebDriverWait(driver, 20)
driver.get('https://app.capitoltrades.com/politician/491')
table = wait.until(EC.visibility_of_element_located((By.XPATH, "//*[@id='pr_id_2']//tr[@class='p-selectable-row ng-star-inserted']"))).text
print(table)
根据您的 BS4 代码,您似乎使用了错误的定位器。
这个:
table = soup.find("table", {"class": "p-datatable-table ng-star-inserted"})
看起来更好(你的 class 名字中有多余的空格)。
上面的行 returns 5 个元素。
所以这应该有效:
table = soup.find("table", {"class": "p-datatable-table ng-star-inserted"}).findAll('tr')
该站点有一个很容易被攻击的后端api:
import requests
import pandas as pd
url = 'https://api.capitoltrades.com/senators/trades/491/false?pageSize=20&pageNumber=1'
resp = requests.get(url).json()
df = pd.DataFrame(resp)
df.to_csv('naughty_nancy_trades.csv',index=False)
print('Saved to naughty_nancy_trades.csv ')
要查看所有数据的来源,请打开浏览器的开发人员工具 - 网络 - fetch/XHR 并重新加载页面,你会看到它们被触发。我抓取了其中一个网络调用,该页面上的所有数据还有其他网络调用