python实现二级页面带自动翻页功能,三级页面爬虫苏宁图书。

最近有在做小学期的项目,用scrapy实现爬取图书,下面是我实现的过程。
具体实现功能有:二级页面带自动翻页功能,三级页面的第一页爬取,大小类别的区分。
框架:scrapy
使用到chrome的插件:Selenium
插件的链接chromediver提权码:5n0l。解压后将他丢入C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe(这是我的路径可以参考下)
数据库:mongoDB
三级页面请看我另外一篇文章:https://blog.csdn.net/weixin_43094046/article/details/107933101

二级页面带自动翻页功能

首先需要在对应的页面下创建scrapy项目这里我们选择创建两个一个叫myProject用于测试xpath因为后期一旦启动项目就开始爬取费时,一个叫suningBook具体实现二级页面带自动翻页功能。
目录:
在这里插入图片描述

废话不多说,直接开淦。
首先选取爬取的页面这里我选择的是小说部分链接:苏宁图书小说
分析页面定位到一整本书
在这里插入图片描述
具体图书页面

然后下面的价格,书名,店铺,评价人数,链接(作为我们跳转的依据)是需要爬取的,这里就不考虑图片了。二级页面中的作者,出版社,出版时间。
在items中定义

import scrapy
class SuningbookItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    id=scrapy.Field()#出版时间
    bkName=scrapy.Field()#图书的名字
    price=scrapy.Field()#图书的价格
    commenrNumber=scrapy.Field()#评价的人数
    bkShop=scrapy.Field()#所在的书店
    bkUrl=scrapy.Field()#URL
    author=scrapy.Field()#作者
    press=scrapy.Field()#出版社
    publishTime=scrapy.Field()#出版时间

在爬取的时候没有考虑数据类型全是字符串,后期在做处理。
写具体爬虫方法

from copy import deepcopy #这里是考虑了数据丢失问题,不然二级页面中数据无法获取

import scrapy


class SuningspiderSpider(scrapy.Spider):
    name = 'suningSpider'
    allowed_domains = ['suning.com']
    start_urls = ['https://list.suning.com/1-502320-0.html']

    def parse(self, response):
        book_lists = response.xpath('//div[@id="filter-results"]/ul/li')
        print(len(book_lists))
        item = {}
        count = 0
        for book in book_lists:#遍历图书
            item['id'] = count+1 #做一个计数器
            item['bkName'] = book.xpath('.//div[@class="res-info"]/p[2]/a/text()').extract_first()
            price1 = str(book.xpath('.//div[@class = "res-info"]/p[1]/em/text()').extract_first())
            price2 = str(
                book.xpath('//*[@id="filter-results"]/ul/li[1]/div/div/div/div[2]/p[1]/em/i[1]/text()').extract_first())
            item["price"] = price1 + price2 #价格拼接
            item['commentNumber'] = book.xpath('.//div[@class="res-info"]/p[3]/a[1]/text()').extract_first()
            item['bkShop'] = book.xpath('.//div[@class="res-info"]/p[4]/a[1]/text()').extract_first()
            item['bkUrl'] = "https:" + book.xpath('.//div[@class="res-info"]/p[2]/a[1]/@href').extract_first()
            yield scrapy.Request(item["bkUrl"], callback=self.parse_detail, meta={"item": deepcopy(item)}) #根据所获取到的url做跳转
            count = count + 1

    def parse_detail(self, response):
        item = response.meta["item"]
        item["author"] = response.xpath('//li[@class="pb-item"][1]/text()').extract_first() if response.xpath('//li[@class="pb-item"][1]/text()').extract_first() is not None else "未知"
        item["press"] = response.xpath('//li[@class="pb-item"][2]/text()').extract_first() if response.xpath('//li[@class="pb-item"][2]/text()').extract_first() is not None else "未知"
        item["publishTime"] = response.xpath('//li[@class="pb-item"][3]/span[2]/text()').extract_first() if response.xpath('//li[@class="pb-item"][3]/text()').extract_first() is not None else "未知"
        yield item
        print(item)

这里的xpath都是通过myProject测试后填写
接下来我们需要翻页所有就使用到了Selenium上文有链接。在middleware中写对应使用的方法,这里我只考虑翻三页。

class SeleniumDownloaderMiddleware:
    """
    构造方法
    """
    def __init__(self):
        self.browser = webdriver.Chrome(r'C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe')  # 每个spider初始化一次driver,自己的Chromedriver路径
    """
    动态网页处理中间件
    """
    def process_request(self, request, spider):#普通selenium的使用
        if spider.name == 'suningSpider'and not (request.url.startswith("https://product")):
            # 根据特定Spider 决定是否利用selenium模拟浏览器爬取
            self.browser.get(request.url)  # selenium请求了网页 获得的Response 因此process_request不需要再返回Request给Downloader
            time.sleep(5)  # 延时5s 待网页完全加载后打印html文本
            print("访问:", request.url)
            print("current_url", self.browser.current_url)
            urlchangecnt = 0
            body = ""
            while (urlchangecnt < 3) :
                self.browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')#这里下滑是因为进入页面只有30本书,要想得到整个页面的图书就需要下滑到底端动作,则数据是60本书
                time.sleep(5)#等待页面加载
                body = body + self.browser.page_source
                self.browser.find_element_by_id('nextPage').send_keys(Keys.ENTER)
                urlchangecnt = urlchangecnt + 1
            return HtmlResponse(self.browser.current_url, body=body,
                                encoding="utf-8", request=request)  # 这里必须返回Response的类或派生类
                                                            #只有这样Scrapy才不会返回Request给Downloader

pipelines中去填写导入数据库的方法,以及数据的清洗

import pymongo
from scrapy.utils.project import get_project_settings
settings = get_project_settings()
class SuningbookPipeline:
    def __init__(self):
        host=settings['MONGODB_HOST']
        port=settings['MONGODB_PORT']
        db_name=settings['MONGODB_DBNAME']
        client=pymongo.MongoClient(host=host,port=port)
        db=client[db_name]
        self.post=db[settings['MONGODB_DOCNAME']]
    def process_item(self, item, spider):
        item["bkName"]=item["bkName"].strip()
        item["commentNumber"]=item["commentNumber"].strip('+')
        item["author"]=item["author"].strip()
        item["press"]=item["press"].strip()
        book_info=dict(item)
        self.post.insert(book_info)
        return item

重要的是在settings里面进行整个项目的配置

BOT_NAME = 'suningBook'

SPIDER_MODULES = ['suningBook.spiders']
NEWSPIDER_MODULE = 'suningBook.spiders'


MONGODB_HOST='127.0.0.1' #数据库地址
MONGODB_PORT=27017
MONGODB_DBNAME='suning' #数据库名
MONGODB_DOCNAME='book_info' #集合的名字
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'suningBook (+http://www.yourdomain.com)'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False #
LOG_LEVEL = 'WARNING' #为了使得控制台输出整洁调整了输出的等级,并且报错会在本地生产log。txt的文件
LOG_FILE = 'log.txt'
CONCURRENT_REQUESTS = 100
COOKIES_ENABLED = False
RETRY_ENABLED = False
DOWNLOAD_TIMEOUT = 3

#下端找到Middleware,pipelins的配置(默认是注释了的),将插件的优先度调整到最高
DOWNLOADER_MIDDLEWARES = {
   'suningBook.middlewares.SuningbookDownloaderMiddleware': 543,
   'suningBook.middlewares.SeleniumDownloaderMiddleware': 1,
}

ITEM_PIPELINES = {
   'suningBook.pipelines.SuningbookPipeline': 300,
}
#这里是做数据输出的缓冲,就不需要在Middleware中数据的睡眠了,使得数据输出完整。
AUTOTHROTTLE_ENABLED = True

遇到的问题:

  1. 数据丢失
  2. 数据爬取过慢
  3. 无法翻页

解决方法:

  1. settings中设置AUTOTHROTTLE_ENABLED = True以及爬虫中的decopy还有我在获取数据中发现数据库中一直都是177条,三页数据本该180条,我就在suningSpider里面第一个函数做item条数输出,发现是180条则我就想是不是这里传给pip出问题还是pip传给数据库出现问题,则我又在pip中打印item。发现数据少了三条就确定了是suningSpider中yield传递的时候出现问题。然后我就在控制台一个id一个ID找发现这个9号并没有在控制台输出,具体到页面上去看发现他的作者和出版时间没有,这样就导致了我的数据丢失,所以就在函数中做了个判断,如果没有的话就填写“未知”,这样的我数据180条就正确了。下面是有问题的图书,只有一个li标签。这是有问题的图书

  2. 在SeleniumDownloaderMiddleware中写了一个判断并不需要具体的每一本输还有进行跳转然后睡眠,只需要获取数据就行and not (request.url.startswith(“https://product”))。以及在settings中CONCURRENT_REQUESTS = 100,并行的数据。

  3. 老师提供的是定位然后点击.click()下一页按钮,发现总是不能,于是我就在网上搜搜.send_keys(Keys.ENTER)发现这个方法模拟键盘回车,能够成功。为了弄清楚,就又尝试了下,发现这个cilck的id定位确实有点问题,用xpath来就行。

以下是数据库截图

数据库截图
整个项目:https://pan.baidu.com/s/1hOR4xJd8JLA_seu9ZwNz8A
提取码:e0zd

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 Python 实现页面自动翻页,你可以使用 Selenium 库来模拟用户的操作。下面是一个示例代码,用于自动翻页: ```python from selenium import webdriver import time # 创建 WebDriver 实例 driver = webdriver.Chrome() # 打开网页 driver.get("https://example.com") # 设置等待时间 driver.implicitly_wait(10) # 自动翻页函数 def auto_pagination(): while True: # 模拟用户操作:滚动到页面底部 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 等待加载新内容 time.sleep(2) # 处理当前页的数据 process_data() # 查找下一页按钮 next_button = driver.find_element_by_xpath("//button[contains(text(), '下一页')]") # 检查是否到达最后一页 if "disabled" in next_button.get_attribute("class"): print("已经到达最后一页") break # 点击下一页按钮 next_button.click() # 处理数据的函数 def process_data(): # 这里可以编写处理当前页数据的代码 print("处理当前页的数据") # 调用自动翻页函数 auto_pagination() # 关闭浏览器窗口 driver.quit() ``` 在上面的代码中,首先通过 `webdriver.Chrome()` 创建了一个 Chrome WebDriver 实例。然后使用 `driver.get()` 打开了目标网页。 接下来,定义了一个 `auto_pagination()` 函数用于自动翻页。在该函数中,使用 `execute_script()` 方法模拟了滚动到页面底部的操作,并通过 `time.sleep()` 等待新内容加载。 然后,调用了 `process_data()` 函数来处理当前页的数据。接着,通过 `driver.find_element_by_xpath()` 查找下一页按钮,并使用 `get_attribute()` 方法获取按钮的 class 属性来检查是否到达最后一页。 最后,通过 `click()` 方法点击下一页按钮,实现自动翻页功能。 请注意,上述代码仅供参考,并且需要根据你实际的网页结构和自动翻页的具体实现进行适当的修改。 如果有任何进一步的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值