如何抓取页面网址未更改但下一个按钮在同一网址页面下方添加数据的网站

Posted

技术标签:

【中文标题】如何抓取页面网址未更改但下一个按钮在同一网址页面下方添加数据的网站【英文标题】:how to scrape website in which page url is not changed but the next button add data below the same url page 【发布时间】:2016-11-30 09:48:56 【问题描述】:

我有一个网址:

http://www.goudengids.be/qn/business/advanced/where/Provincie%20Antwerpen/what/restaurant

在该页面上有一个“下一个结果”按钮,它加载另外 20 个数据点,同时仍显示第一个数据集,而不更新 URL。我编写了一个脚本来在 python 中抓取这个页面,但它只抓取前 22 个数据点,即使单击“下一个结果”按钮并显示大约 40 个数据。

如何抓取这些动态加载内容的网站

我的脚本是

import csv
import requests
from bs4 import BeautifulSoup


url = "http://www.goudengids.be/qn/business/advanced/where/Provincie%20Antwerpen/what/restaurant/"
r = requests.get(url)
r.content

soup = BeautifulSoup(r.content)
print (soup.prettify())

g_data2 = soup.find_all("a", "class": "heading")
for item in g_data2:
    try:
        name = item.text
        print name
    except IndexError:
        name = ''
        print "No Name found!"

【问题讨论】:

【参考方案1】:

如果您要使用requests 来解决它,您需要模仿浏览器在单击“加载更多”按钮时所做的事情——它会向http://www.goudengids.be/q/ajax/business/results.json 端点发送一个XHR 请求,在维护网络抓取会话的代码中模拟它。 XHR 响应采用 JSON 格式 - 在这种情况下根本不需要 BeautifulSoup

import requests

main_url = "http://www.goudengids.be/qn/business/advanced/where/Provincie%20Antwerpen/what/restaurant/"
xhr_url = "http://www.goudengids.be/q/ajax/business/results.json"
with requests.Session() as session:
    session.headers = 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/51.0.2704.103 Safari/537.36'

    # visit main URL
    session.get(main_url)

    # load more listings - follow the pagination
    page = 1
    listings = []
    while True:
        params = 
            "input": "restaurant Provincie Antwerpen",
            "what": "restaurant",
            "where": "Provincie Antwerpen",
            "type": "DOUBLE",
            "resultlisttype": "A_AND_B",
            "page": str(page),
            "offset": "2",
            "excludelistingids": "nl_BE_YP_FREE_11336647_0000_1746702_6165_20130000, nl_BE_YP_PAID_11336647_0000_1746702_7575_20139729427, nl_BE_YP_PAID_720348_0000_187688_7575_20139392980",
            "context": "SRP * A_LIST"
        
        response = requests.get(xhr_url, params=params, headers=
            "X-Requested-With": "XMLHttpRequest",
            "Referer": main_url
        )
        data = response.json()

        # collect listing names in a list (for example purposes)
        listings.extend([item["bn"] for item in data["overallResult"]["searchResults"]])

        page += 1

        # TODO: figure out exit condition for the while True loop

    print(listings)

我为您留下了一个重要的 TODO - 找出退出条件 - 何时停止收集列表。

【讨论】:

当我运行你的脚本时,它给了我一条错误消息 Traceback (最近一次调用最后一次):文件 "C:\Users\User\Desktop\python\script\3url.py",第 3 行,在 中使用 requests.Session() 作为会话:NameError: name 'requests' is not defined 我该如何解决?? @vishnu 将此import requests 放在顶部?这个很重要。而且你必须安装requests 模块。 你是对的@alecxe 我真的忘记了。感谢您的大力帮助,我将来也需要您 @alexce 这里我在这个链接中有另一个 URL theknowledgeonline.com/production-companies 我需要抓取姓名地址电话号码电子邮件等。但是没有直接找到数据。我需要点击每个链接,它会进入新页面,提供完整的数据。如何抓取这些类型的 URL??【参考方案2】:

我认为您应该查看通过 AJAX 检索的 JSON,而不是专注于抓取 HTML。我认为与页面标记相比,JSON 在未来不太可能被更改。最重要的是,遍历 JSON 结构比抓取 DOM 更容易。

例如,当您加载您提供的页面时,它会点击一个 URL 以获取位于 http://www.goudengids.be/q/ajax/business/results.json 的 JSON。

然后提供一些url参数来查询商家。我认为您应该更多地研究使用它来获取数据,而不是抓取页面和模拟按钮点击等。

编辑:

它看起来像是在使用最初访问该站点时设置的标题来确保您有一个有效的会话。因此,您可能必须首先访问该站点以获取 cookie 标头并将其设置为后续请求以从上述端点获取 JSON。我仍然认为这会比尝试抓取 HTML 更容易且更可预测。

【讨论】:

以上是关于如何抓取页面网址未更改但下一个按钮在同一网址页面下方添加数据的网站的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Python和Selenium分页来抓取页面

使用 selenium 在 LinkedIn 上抓取个人资料网址

如何让Googlebot抓取从AJAX加载的内容,但阻止它对网址命中的索引?

如何更改浏览器网址框中的网址?

如何更改 ExtJs 中每个页面的网址?

访问新网址赛普拉斯