使用相同的 url 从不同的页面抓取数据

Scrape data from different pages with same url

提问人:the_special_none 提问时间:7/31/2022 最后编辑:the_special_none 更新时间:7/31/2022 访问量:320

问:

我正在尝试从此网页(https://www.fplanalytics.com/history1213.html)中抓取数据。我能够从第一页抓取数据,但是一旦我尝试转到下一页,它就会不断返回相同的数据。我注意到它总是检索相同的 URL。

有没有人知道如何从以下页面获取数据?


import requests
import os
import shutil
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
import time
import pandas as pd
from bs4 import BeautifulSoup

#  create list for html years
years= list(range(1213,2122,101))

# import html into python
driver = webdriver.Chrome(
   "C:/Users/aldi/Downloads/chromedriver.exe")
driver.get('https://www.fplanalytics.com/history1213.html')
driver.maximize_window()

soup = BeautifulSoup(driver.page_source, 'html.parser')
table = soup.find('table', {'id':'data-table'})

#create empty dataframe and name columns
columns_names = ["player","team","position", "minutes", "goals", "assists", "cs", "tot pts", "bonus"]
df = pd.DataFrame(columns = columns_names)

#grab table in one page
#trs = table.find_all('tr')[1:]
#for row in trs:
#    row_data = row.find_all('td')
#    row = [td.text for td in row_data]
#    length = len(df)
#    df.loc[length] = row
    
    
while True: 
    soup = BeautifulSoup(driver.page_source, 'html.parser')
    table = soup.find('table', {'id':'data-table'})
    trs = table.find_all('tr')[1:]
    for row in trs:
        row_data = row.find_all('td')
        row = [td.text for td in row_data]
        length = len(df)
        df.loc[length] = row
    try:
        #grabs the url of the next page
        next_page = soup.find('a', class_ = 'page-link').get('href')
        next_page = 'https://www.fplanalytics.com/history1213.html'+next_page
#        driver.get(next_page)
    except:
        break
    
    #Imports the next pages HTML into python
    page = requests.get(next_page)
    soup = BeautifulSoup(page.text, 'lxml')
html selenium selenium-webdriver 网页抓取

评论

0赞 Himanshu Poddar 7/31/2022
为什么要使用 Selenium 和 BS4 的组合。如果数据是动态的,则仅使用硒!

答:

1赞 Barry the Platipus 7/31/2022 #1

数据由处理数据表的 Javascript 动态加载到页面中。可以在开发工具中检查“网络”选项卡,并尝试直接抓取该数据终结点。例如:

import requests
import pandas as pd

headers = {
    'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'en-US,en;q=0.9',
'Connection': 'keep-alive',
'Host': 's3.eu-central-1.amazonaws.com',
'Origin': 'https://www.fplanalytics.com',
'Referer': 'https://www.fplanalytics.com/',
'sec-ch-ua': '"Chromium";v="103", ".Not/A)Brand";v="99"',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'cross-site',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36'
}
r = requests.get('https://s3.eu-central-1.amazonaws.com/fpl.data/db/history201213.json?_=1659263770681', headers=headers)
df = pd.DataFrame(r.json())
print(df)

这将返回一个包含 422 行× 17 列的数据帧:

name    team    position    minutes goals   assists cs  yc  rc  saves   bonus   points  gc  og  ps  pm  _row
0   [Baird] [FUL]   [DEF]   1320    2   0   2   5   0   0   3   45  20  0   0   0   BairdFULDEF
1   [Riise] [FUL]   [DEF]   2529    0   5   8   4   0   0   7   95  41  0   0   0   RiiseFULDEF
2   [Senderos]  [FUL]   [DEF]   1684    0   0   5   6   0   0   1   48  25  0   0   0   SenderosFULDEF
3   [Riether]   [FUL]   [DEF]   3043    1   6   7   4   0   0   11  109 53  0   0   0   RietherFULDEF
4   [Hughes]    [FUL]   [DEF]   2115    0   0   4   1   0   0   3   50  43  0   0   0   HughesFULDEF
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...

评论

0赞 ASH 8/1/2022
我尝试从platipus_on_fire运行代码。它对我不起作用。我尝试运行 F.Hoque 的代码,它对我来说完全正常。有人可以分享一些关于这个解决方案如何工作的见解吗?我在这个话题上看到了一些类似的问题。我从来没有弄清楚整个标头 = {etc} 的东西是如何工作的。有关于这个的教程吗?有没有一些网站来解释这个概念?谢谢!!
0赞 Barry the Platipus 8/1/2022
我只是按照上面写的再次运行它,它有效。例如,您必须更新您的软件包。你复制正确了吗?您收到了什么错误?pip install -U requests
0赞 ASH 8/1/2022
是的,它现在正在工作。不知道之前发生了什么。你是怎么想出这个解决方案的?有没有一个网站可以解释这个“mozilla/headers”是如何工作的?
1赞 Barry the Platipus 8/1/2022
当您检查“网络”选项卡并单击 XHR 请求时,它将显示更多详细信息,例如 - 您只需重新创建即可。标头只不过是访问 url 的浏览器/机器人向服务器展示自己的方式。根据标头,服务器可以选择接受或拒绝浏览器的请求。Request Headers
0赞 ASH 8/1/2022
哦,我明白了!很酷!感谢您分享此见解!!