【问题标题】:Why does this not work? Python webscraping为什么这不起作用? Python网页抓取
【发布时间】:2021-12-19 00:43:01
【问题描述】:

enter image description here我用这段代码来取回li标签内的所有文本,但它不起作用。

from bs4 import BeautifulSoup
import requests
page = requests.get("https://archief.amsterdam/inventarissen/scans/31245/120.3")
soup = BeautifulSoup(page.content, 'html.parser')
result = soup.find_all('#modal > div > div.content > div > div > ul > li:nth-child(1) > span.file-name')

for i in range(len(result)):
    print(result[i].text.strip())

print(len(result))

image of the website where i want data from

【问题讨论】:

    标签: python html css web beautifulsoup


    【解决方案1】:

    看起来该站点正在使用 JavaScript 创建这些标签,而 requests 模块根本不运行 JS,因此这些标签从未出现在 page.content 中。

    您可以使用 requests-htmlSelenium 之类的东西来允许 JS 在您访问内容之前运行,或者直接抓取页面加载的数据(我检查了,并且有一个向服务器发出的请求返回您需要的 JSON 格式的数据。在加载页面时检查浏览器开发人员工具的网络选项卡以获取更多信息/如果您想使用它)。

    还有,

    • 假设您想要获取每个文件名,您可以将选择器简化为 li span.file-name
    • Python 支持这样的 for 循环:for result in results,因此您可以使用它来代替更传统的/JavaScript-y 类型。下面我举个例子。
    # This is assuming the "result" variable is renamed to "results".
    for result in results:
        print(result.text.strip())
    
    print(len(results))
    

    数据抓取方法(回复评论)

    1. 将调用requests.get 中的网页 URL 替换为 API。
    2. 将服务器返回的JSONP文本转换为常规JSON,以便我们可以使用Python的标准json库对其进行解析。
    3. 遍历解析的 JSON,提取“name”的值并将其添加到某个列表中。

    完整示例:

    import json
    import requests
    
    # The URL from the network tab.
    api_url = "https://webservices.picturae.com/archives/scans/31245/120.3?apiKey=eb37e65a-eb47-11e9-b95c-60f81db16c0e&lang=nl_NL&findingAid=31245&path=120.3&callback=callback_json5"
    response = requests.get(api_url)
    # The split() and strip() calls here remove parts of the request
    # that are JSONP, not JSON. We need just the JSON data.
    raw_json = response.text.split("(", 1)[1].strip(")")
    # Load the JSON data into a regular Python dictionary.
    data = json.loads(raw_json)
    # Add all the filenames from the data into the filenames list.
    filenames = []
    for scan in data["scans"]["scans"]:
        filename = scan["name"]
        print(filename)
        filenames.append(filename)
    
    print("\nFilename count:", len(filenames))
    

    【讨论】:

    • 感谢您的提示,我查看了网络选项卡,确实包含我真正需要的内容。你知道我如何用 python 检索这个
    • 我添加了一张图片作为解释
    • @FezTalmest 我更新了我的答案,解释了如何做到这一点和一个例子。希望这会有所帮助!
    • 非常感谢,成功了!
    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 2022-01-28
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 2017-02-10
    • 2020-10-27
    相关资源
    最近更新 更多