首页 > 解决方案 > 如果搜索产生的结果多于显示的结果,则抓取隐藏页面

问题描述

在https://www.comparis.ch/carfinder/default下输入的一些搜索查询会产生超过 1'000 个结果(在搜索页面上动态显示)。然而,结果最多只显示 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] = {}

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

标签: pythonweb-scrapingbeautifulsoup

解决方案


您的网站似乎在客户端浏览时加载数据。可能有很多方法可以解决这个问题。一种选择是使用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. from scrapy_splash import SplashRequest在你的 spider.py 中导入
  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. 通过修改将 url 重定向到启动服务器def start_requests(self):

比如像这样

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

让我知道这对你有什么影响。


推荐阅读