使用 Scrapy 和 Selenium 爬取懂车帝排行榜数据

313 阅读4分钟

使用 Scrapy 和 Selenium 爬取懂车帝排行榜数据

免责声明: 本文所提供的教程、源码和软件仅用于技术研究和学习目的。在使用这些工具和信息时,请确保遵循适用的法律法规,并尊重网站的使用条款和隐私政策。本文不鼓励、支持或参与任何非法活动,包括但不限于未经授权的信息采集、计算机系统攻击或侵犯隐私。 读者在使用本文提供的代码和方法时,应该明白并遵循道德准则,确保其行为不会影响计算机信息系统的正常运行,不会对他人造成任何损害。任何非法使用或滥用所提供的信息和工具,与本文作者无关。 请谨慎使用爬虫技术,保持合法、道德的使用行为,以维护网络空间的健康和秩序。

引言

在这篇文章中,我会介绍如何使用 Scrapy 和 Selenium 结合的方式来爬取懂车帝网站的排行榜信息。懂车帝是一个提供汽车信息的综合平台,本文通过搭建一个 Scrapy 爬虫,利用 Selenium 控制浏览器进行动态加载的页面爬取。之前已经讲解了Scrapy的使用,这篇文章的主要目的是引入Selenium的使用。

简介

首先,让我们了解一下我们要爬取的目标 - 懂车帝的排行榜。排行榜页面通常包含了各种汽车的信息,包括车型、价格、销量等。我们的目标是从这些页面中提取数据,以便进一步的分析或展示。

准备

安装 Scrapy 和 Selenium

确保你已经安装了 Scrapy 和 Selenium。你可以使用以下命令进行安装:

pip install scrapy selenium

创建 Scrapy 项目

通过以下命令创建一个新的 Scrapy 项目:

scrapy startproject dongchedi_rankings
cd dongchedi_rankings

配置项目

settings.py 文件中,确保以下配置项的设置:

# Enable and configure the AutoThrottle extension (disabled by default)
AUTOTHROTTLE_ENABLED = True
AUTOTHROTTLE_START_DELAY = 5
AUTOTHROTTLE_MAX_DELAY = 60
AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
AUTOTHROTTLE_DEBUG = False

# Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html
EXTENSIONS = {
    'scrapy.extensions.telnet.TelnetConsole': None,
}

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
    'dongchedi_rankings.pipelines.DongchediRankingsPipeline': 300,
}

# Selenium settings
SELENIUM_DRIVER_NAME = 'chrome'
SELENIUM_DRIVER_EXECUTABLE_PATH = '/path/to/chromedriver'
SELENIUM_DRIVER_ARGUMENTS=['--headless']  # 可选,用于无头浏览器模式

确保将 'dongchedi_rankings.pipelines.DongchediRankingsPipeline' 添加到 ITEM_PIPELINES 中,以便处理提取的数据。

编写爬虫

创建爬虫

spiders 目录下创建一个名为 dongchedi_spider.py 的文件,并编写如下内容:

# dongchedi_rankings/spiders/dongchedi_spider.py
import scrapy
from selenium import webdriver
from dongchedi_rankings.items import DongchediRankingItem
import time

class DongchediSpider(scrapy.Spider):
    name = 'dongchedi_spider'
    start_urls = ['https://www.dongchedi.com/sales']

    def __init__(self, *args, **kwargs):
        # 初始化Selenium WebDriver
        self.driver = webdriver.Chrome()
        super(DongchediSpider, self).__init__(*args, **kwargs)

    def parse(self, response):
        # 使用Selenium控制浏览器打开初始URL
        self.driver.get(response.url)
        
        # 获取初始页面的滚动高度
        last_height = self.driver.execute_script("return document.body.scrollHeight")

        while True:
            # 模拟滚动页面以触发更多内容加载
            self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            time.sleep(3)  # 等待加载完成,可以根据网速适当调整

            # 获取新的滚动高度
            new_height = self.driver.execute_script("return document.body.scrollHeight")

            # 获取更新后的页面源代码
            updated_html = self.driver.page_source
            updated_response = scrapy.http.HtmlResponse(url=self.driver.current_url, body=updated_html, encoding='utf-8')

            # 如果滚动高度不再增加,说明已经滑到了页面底部
            if new_height == last_height:
                # 提取数据
                car_list = updated_response.xpath('//*[@id="__next"]/div[1]/div[2]/div/div[4]/div/div/ol/li')
                for car in car_list:
                    car_name = car.xpath('./div[3]/div[1]/a/text()').get()
                    car_price = car.xpath('./div[3]/p/text()').get()
                    car_image = car.xpath('./div[2]/div/div/img/@src').get()
                    sales_trend = car.xpath('./div[4]/div/p/text()').get()

                    item = DongchediRankingItem()
                    item['CarName'] = car_name.strip()
                    item['PriceRange'] = car_price.strip()
                    item['CarImage'] = 'https:' + car_image.strip()
                    item['SalesTrend'] = sales_trend.strip()

                    yield item

                # 跳出循环,结束爬取
                break

            # 更新滚动高度,准备下一次判断
            last_height = new_height  

        # 完成后关闭浏览器
        self.driver.quit()

编写 Item

items.py 文件中定义我们要提取的数据结构:

# dongchedi_rankings/items.py
import scrapy

class DongchediRankingItem(scrapy.Item):
    CarName = scrapy.Field()
    PriceRange = scrapy.Field()
    CarImage = scrapy.Field()
    SalesTrend = scrapy.Field()

运行爬虫

最后,我们运行 Scrapy 爬虫:

scrapy crawl dongchedi_spider

爬虫将开始运行,通过 Selenium 模拟浏览器行为,动态加载页面并提取排行榜数据。数据将保存在 dongchedi_rankings.json 文件中。

运行结果

下面是dongchedi_rankings.json 文件截图:

WX20231110-104819@2x.png

总结

通过结合 Scrapy 和 Selenium,我们成功地构建了一个强大的爬虫,可以应对动态加载的页面。在实际应用中,你可以根据需要进行更多的定制,添加异常处理、自定义中间件等,以确保爬虫的稳定性和性能。

通过这篇文章,你应该对使用 Scrapy 和 Selenium 进行动态页面爬取有了更深入的理解。希望这能够帮助你在实际项目中更好地应用这两个强大的工具。

本案例源码已上传Github