初探Scrapy爬虫框架之百度网页爬取

scrapy框架及百度网页爬取与保存

大家好,最近本科即将毕业,即将迎来研究生生涯,可能自己的研究方向和大数据人工智能有关,那自然免不了网络爬虫的学习。之前接触过request库用于网络爬虫,但为了后续框架式的系统开发,我尝试开始使用Scrapy框架,希望记录一下自己的学习过程,和大家一起交流分享。

一、scrapy框架简介

太多的专业性解释我这里就不提了,我也是刚接触scrapy框架,我也不想长篇大作的从网上复制粘贴,但我可以从我自己这段时间的学习过程,给你们推荐一下比较适合新手看的一篇关于scrapy的学习博客,可以帮助我们从整体对scrapy框架有一个认识。

  1. 爬虫框架Scrapy个人总结(详细)熟悉

二、自己初使用的心得体会

可能有错,欢迎批评指正:

1、爬虫之前明确目标

整体考虑的问题有两点:
1、我们要从哪里爬 :例如本次我测试就是从百度搜索引擎爬,再比如你的爬取目标可能是小说网站,也可能是电影网站,音乐网站,淘宝等
2、我们要爬哪些内容:例如本次我测试就是简单地根据搜索百度关键字爬取相应数量的网页,再比如你的目标是电影网站,那你可能想爬电影名称及对应的url链接等
总之,我们不可急于求成,一定要明白此次爬虫的目标及内容,后续工作才更好展开。

2、scrapy框架的简单使用流程

1、编写items.py:第一步我们需要编写items.py,即存放我们要保存的的数据的容器。这里就体现出了我们刚刚第一步明确爬取内容的优势了,例如我们可以在这里定义电影标题,电影url等变量,当然,我们后续可以继续在这添加可能开始遗漏的变量。

import scrapy
class SpiderItems(scrapy.Item): #创建一个类,继承scrapy.item类
title = scrapy.Field() # 根据自己要爬取的内容进行创建
url = scrapy.Field()
...

2、编写spider.py:第二步我们需要编写自己的爬虫程序,这也是我们爬虫最关键的一部分,用于爬取我们想要内容的具体方式细节。初始化:name变量为该爬虫py文件名,allowed_domains变量为限定我们爬取的域名(不用加http开头),start_urls变量为初始化爬取的url链接。

class Spider(scrapy.Spider): # 继承Spider类
    name = "spider" # 爬虫的唯一标识,不能重复,启动爬虫的时候要用
    allowed_domains = ['www.baidu.com'] # 限定域名,只爬取该域名下的网页
    start_urls = ["http://www.baidu.com/" ] # 开始爬取的链接  

parse函数其实就是初始的回调函数,即程序会将初始化的url链接发起request请求,随后程序会将响应结果作为参数传递给parse函数的response,我们在parse函数中就可以对response进行处理,解析出的item内容信息可以通过yield item传递给 pipelines.py做进一步数据处理,解析出的url则加入爬取队列,负责进一步处理。
3、编写pipelines.py:第三步我们需要编写自己的数据处理程序,即对我们在spider.py中提取到的item数据进行处理与保存
4、编写middlewares.py(非必须):第四步是非必须的一步,是根据自己的需要去实现,其中包括两大部分:Downloader Middlewares:下载中间件,是处于Scrapy的Request和Requesponse之间的处理模块;Spider Middlewares:spider中间件,位于引擎和spider之间的框架,主要处理spider输入的响应和输出的结果及新的请求。
5、在settings.py中进行相关的设置:第五步是主要对全局的一些爬虫细节进行自定义的设置,详细可参考scrapy中的setting详解

3、scrapy框架的整体运行过程

我们不难从网上发现什么关于scrapy框架的介绍及初步使用教程,但从我自己刚刚学习起来,总有一种感觉就是似懂非懂,就是你通过查阅相关资料你可能很快掌握scrapy框架各部分大致要干什么,但你就是很难从整体掌握它们之间的联系,下面简要阐述作为初学者对于scrapy框架整体运行过程的理解:

在这里插入图片描述
具体解释如下:
Spiders,可以视为我们的spider.py,可见;Item Pipeline可以视为我们处理item的pipelines.py,可见;Scrapy Engine为引擎,处理整个系统的数据流处理,不可见;Scheduler为调度器,接受引擎发过来的请求,并将其加入队列中,在引擎再次请求时将请求提供给引擎,不可见;Downloader:下载器,下载网页内容,并将响应返回给spider,不可见;Downloader Middlewares:下载中间件,是处于Scrapy的Request和Requesponse之间的处理模块,在middlewares.py中可以自定义编写,可见;Spider Middlewares:spider中间件,位于引擎和spider之间的框架,主要处理spider输入的响应和输出的结果及新的请求,在middlewares.py中可以自定义编写,可见。
详细流程参考如下:

1.spider的yeild将request发送给engine
2.engine对request不做任何处理发送给scheduler
3.scheduler,生成request交给engine
4.engine拿到request,通过middleware发送给downloader
5.downloader在\获取到response之后,又经过middleware发送给engine
6.engine获取到response之后,返回给spider,spider的parse()方法对获取到的response进行处理,解析出items或者requests
7.将解析出来的items或者requests发送给engine
8.engine获取到items或者requests,将items发送给ItemPipeline,将requests发送给scheduler(注意:只有调度器中不存在request时,程序才停止,及时请求失败scrapy也会重新进行请求)

三、百度网页爬取及保存流程

1、初始url的构造

我们用浏览器打开百度搜索页面,输入关键字,这里我们输入“python”,可以看见url为https://www.baidu.com/baidu?wd=python&tn=monline_3_dg&ie=utf-8
在这里插入图片描述
不难看出wd参数代表我们的关键字信息,其余参数我们可以忽略,由此我们可以构造初始的url的代码为:‘https://www.baidu.com/baidu?wd={}’.format(keyword).

2、网页标题及url链接的提取

在百度搜索结果页面按F12,即打开了开发者工具,我们现在假设要定位到本页的第一个网页的标题,则可以按以下操作进行:
在这里插入图片描述
即可以直接定位到标题所在的部分,结果如下:
在这里插入图片描述
我们观察分析该标题所在html的位置(我们这里没有采取正则表达式的方式,因为对初学者可能难度较大,而是采用XPath的方式,具体参考这个链接,我个人感觉这种提取html内容的方式很适合初学者),可以写成如下的表达式://div[@id=“wrapper_wrapper”]/div[@id=“container”]/div[@id=
“content_left”]//h3/a/em/text(),同理,每个网页的真实url也可以此种形式进行提取,表达式为:
//div[@id=“wrapper_wrapper”]/div[@id=“container”]/div[@id=“content_left”]//h3/a/@href。

3、百度翻页操作

翻页,其实就是我们爬取完了一页的内容信息,想继续往下一页进行爬取,此时我们需要找到“下一页”按钮对应的跳转链接,方法一样,就是先选中“下一页”,找到在html的位置,再用XPath提取该链接,表达式为://div[@id=“page”]/a[contains(text(),“下一页”)]/@href,提取到后就可以作为新的url发起请求,获取下一页的内容再循环进行爬取。
在这里插入图片描述

4、应对百度的反爬虫机制策略

参考链接
我刚开始尝试爬取百度网页时,没有添加任何的应对反爬虫的机制,发现一个信息都爬不下来,简直就是还没开始就结束了,后来查阅资料发现百度这些年做了很多反爬虫机制,所以如果想像爬取其它小网站的形式去爬百度,基本不可能了,我主要采用了两种机制:随机user-agent和随机请求延时,具体怎么操作,直接参考我贴的代码(middlewares.py)如下:

from scrapy import signals
import random
import time
class SpiderSpiderMiddleware: # 默认生成的,没有使用到,可以忽略
    # Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the spider middleware does not modify the
    # passed objects.

    @classmethod
    def from_crawler(cls, crawler):
        # This method is used by Scrapy to create your spiders.
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_spider_input(self, response, spider):
        # Called for each response that goes through the spider
        # middleware and into the spider.

        # Should return None or raise an exception.
        return None

    def process_spider_output(self, response, result, spider):
        # Called with the results returned from the Spider, after
        # it has processed the response.

        # Must return an iterable of Request, dict or Item objects.
        for i in result:
            yield i

    def process_spider_exception
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值