【问题标题】:scrape hidden pages if search yields more results than displayed如果搜索产生的结果多于显示的结果,则抓取隐藏页面
【发布时间】:2020-01-03 08:35:37
【问题描述】:

https://www.comparis.ch/carfinder/default 下输入的某些搜索查询会产生超过 1000 个结果(在搜索页面上动态显示)。然而,结果最多只显示 100 页,每页有 10 个结果,所以我试图在给定产生超过 1'000 个结果的查询的情况下抓取剩余的数据。 抓取前 100 个页面的 ID 的代码是(运行所有 100 个页面大约需要 2 分钟):

from bs4 import BeautifulSoup
import requests

# as the max number of pages is limited to 100
number_of_pages = 100

# initiate empty dict
car_dict = {}

# parse every search results page and extract every car ID
for page in range(0, number_of_pages + 1, 1):
    newest_secondhand_cars = 'https://www.comparis.ch/carfinder/marktplatz/occasion'
    newest_secondhand_cars = requests.get(newest_secondhand_cars + str('?page=') + str(page))
    newest_secondhand_cars = newest_secondhand_cars.content
    soup = BeautifulSoup(newest_secondhand_cars, "lxml")

    for car in list(soup.find('div', {'id': 'cf-result-list'}).find_all('h2')):
        car_id = int(car.decode().split('href="')[1].split('">')[0].split('/')[-1])
        car_dict[car_id] = {}

所以我显然尝试只传递一个大于 100 的 str(page),这不会产生额外的结果。 如果有的话,我如何访问剩余的结果?

【问题讨论】:

  • 有时这些结果会在浏览器中使用 javascript 加载,这意味着您必须解决这个问题。您能否通过查看浏览器中的结果来验证这没有发生。
  • 页面上的实际结果在 id 为“result_list_ajax_container”的 div 中,这表明它们是动态加载的。您对此有何猜测?
  • 我同意。这似乎表明结果是在浏览时在客户端加载的。你需要的是 Scrapy-Splash。它充当将呈现任何 javascript 的客户端,然后您从该客户端抓取。如果您知道如何使用 docker,这可能是最简单的入门方法:github.com/scrapy-plugins/scrapy-splash
  • 使用Selenium来控制可以运行JavaScript的网络浏览器。安装为Scrapy 创建的Splash 会更简单

标签: python web-scraping beautifulsoup


【解决方案1】:

您的网站似乎在客户端浏览时加载数据。可能有很多方法可以解决这个问题。一种选择是使用Scrapy Splash

假设您使用的是scrapy,您可以执行以下操作:

  1. 使用 docker 启动 Splash 服务器 - 记下
  2. settings.py 添加SPLASH_URL = <splash-server-ip-address>
  3. settings.py 添加到中间件

这段代码:

DOWNLOADER_MIDDLEWARES = {
    'scrapy_splash.SplashCookiesMiddleware': 723,
    'scrapy_splash.SplashMiddleware': 725,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
  1. 在您的 spider.py 中导入 from scrapy_splash import SplashRequest
  2. 在您的 spider.py 中设置 start_url 以遍历页面

例如像这样

base_url = 'https://www.comparis.ch/carfinder/marktplatz/occasion'
start_urls = [
     base_url + str('?page=') + str(page) % page for page in range(0,100)      
    ]
  1. 通过修改def start_requests(self):将url重定向到启动服务器

例如像这样

def start_requests(self):
    for url in self.start_urls:
        yield SplashRequest(url, self.parse,
            endpoint='render.html',
            args={'wait': 0.5},
        )
  1. 像现在一样解析响应。

让我知道你的效果如何。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 2018-12-19
    • 2016-04-07
    相关资源
    最近更新 更多