【问题标题】:How do I get the URLs for all the pages?如何获取所有页面的 URL?
【发布时间】:2021-07-04 01:19:18
【问题描述】:

我有一个代码可以从“oddsportal”网站收集一个页面的所有 URL:

from bs4 import BeautifulSoup
import requests

headers = {
    'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'}
source = requests.get("https://www.oddsportal.com/soccer/africa/africa-cup-of-nations/results/",headers=headers)

soup = BeautifulSoup(source.text, 'html.parser')
main_div=soup.find("div",class_="main-menu2 main-menu-gray")
a_tag=main_div.find_all("a")
for i in a_tag:
    print(i['href'])

返回这些结果:

/soccer/africa/africa-cup-of-nations/results/
/soccer/africa/africa-cup-of-nations-2019/results/
/soccer/africa/africa-cup-of-nations-2017/results/
/soccer/africa/africa-cup-of-nations-2015/results/
/soccer/africa/africa-cup-of-nations-2013/results/
/soccer/africa/africa-cup-of-nations-2012/results/
/soccer/africa/africa-cup-of-nations-2010/results/
/soccer/africa/africa-cup-of-nations-2008/results/

我希望将网址返回为:

https://www.oddsportal.com/soccer/africa/africa-cup-of-nations/results/
https://www.oddsportal.com/soccer/africa/africa-cup-of-nations/results/#/page/2/
https://www.oddsportal.com/soccer/africa/africa-cup-of-nations/results/#/page/3/

对于为results 生成的所有父 url。

我可以看到可以从检查元素中看到 URL 可以附加如下div id = "pagination"

【问题讨论】:

    标签: python web-scraping beautifulsoup


    【解决方案1】:

    id="pagination"下的数据是动态加载的,所以requests不支持。

    但是,您可以通过向以下地址发送GET 请求来获取所有这些页面 (1-3) 的表格:

    https://fb.oddsportal.com/ajax-sport-country-tournament-archive/1/MN8PaiBs/X0/1/0/{page}/?_={timestampe}"
    

    其中{page}对应页码(1-3),{timestampe}是当前时间

    您还需要添加:

    "Referer": "https://www.oddsportal.com/"
    

    到您的headers。 另外,使用lxml 解析器而不是html.parser 来避免RecursionError

    import re
    import requests
    from datetime import datetime
    from bs4 import BeautifulSoup
    
    headers = {
        "User-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
        "Referer": "https://www.oddsportal.com/",
    }
    
    
    with requests.Session() as session:
        session.headers.update(headers)
        for page in range(1, 4):
            response = session.get(
                f"https://fb.oddsportal.com/ajax-sport-country-tournament-archive/1/MN8PaiBs/X0/1/0/{page}/?_={datetime.now().timestamp()}"
            )
    
            table_data = re.search(r'{"html":"(.*)"}', response.text).group(1)
            soup = BeautifulSoup(table_data, "lxml")
            print(soup.prettify())
    

    【讨论】:

    • 1) 应该是Session() 而不是session(), 2) 你应该使用session.get 而不是requests.get 否则你在这里什么都不做!
    • 欢迎您,注意您处理的是AJAXtimed,其中end参数等于时间戳,也就是说,只要您要寻找新鲜的结果,您应该使用查询当前时间的时间戳。 ?_=1625363690901"
    • 把它留给 OP,因为获取当前时间戳是非常基本的事情,作为站点贡献者,您不需要将每个调用的标题分配为 headers=headers,就在您的for 循环之前,您可以将其分配给会话一次作为session.headers.update(headers),这将根据timeit 将性能提高10 倍。您也不需要使用 str(response.content) 将字节转换为字符串!直接用response.text就行了!
    • @αԋɱҽԃαмєяιcαη 这些 cmets 非常有用。谢谢你。 Session 总是比普通请求更好用吗?
    • @MasayoMusic lxml 是比html.parser 最快的解析器,只需根据docs-comparsion 使用lxml。递归错误不是html 解析器中的错误,但是根据python-bug-reports,有一些奇怪的 HTML 结构会混淆解析器
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 2017-12-15
    相关资源
    最近更新 更多