irpas技术客

scrapy爬虫之爬取百度手机助手app信息并保存至mongodb数据库(附源码)_阿尔的阳光y

未知 6756

声明:

? 本文内容仅供学习python爬虫的同学用作学习参考!!!

? 如有错误,请评论指出,非常感谢!!!

1.使用环境

python 3.8

scrapy 2.5

mongodb

pycharm

2.通用爬虫CrawlSpider介绍

? CrawlSpider是Scrapy提供的一个通用Spider。在Spider里,我们可以指定一些爬取规则来实现页面的提取,这些爬取规则由一个专门的数据结构Rule表示。Rule里包含提取和跟进页面的配置,Spider会根据Rule来确定当前页面中的哪些链接需要继续爬取、哪些页面的爬取结果需要用哪个方法解析等。

? CrawlSpider继承自Spider类。除了Spider类的所有方法和属性,它还提供了一个非常重要的属性和方法。

rules,它是爬取规则属性,是包含一个或多个Rule对象的列表。每个Rule对爬取网站的动作都做了定义,CrawlSpider会读取rules的每一个Rule并进行解析。

parse_start_url(),它是一个可重写的方法。当start_urls里对应的Request得到Response时,该方法被调用,它会分析Response并必须返回Item对象或者Request对象。

? 这里最重要的内容莫过于Rule的定义了,它的定义和参数如下所示:

class scrapy.contrib.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None)

下面将依次说明Rule的参数。

link_extractor:是Link Extractor对象。通过它,Spider可以知道从爬取的页面中提取哪些链接。提取出的链接会自动生成Request。它又是一个数据结构,一般常用LxmlLinkExtractor对象作为参数,其定义和参数如下所示:

class scrapy.linkextractors.lxmlhtml.LxmlLinkExtractorallow=(), deny=(), allow_domains=(), deny_domains=(), deny_extensions=None, restrict_xpaths=(), restrict_css=(), tags=('a', 'area'), attrs=('href', ), canonicalize=False, unique=True, process_value=None, strip=True)

? allow是一个正则表达式或正则表达式列表,它定义了从当前页面提取出的链接哪些是符合要求的,只有符合要求的链接才会被跟进。deny则相反。allow_domains定义了符合要求的域名,只有此域名的链接才会被跟进生成新的Request,它相当于域名白名单。deny_domains则相反,相当于域名黑名单。restrict_xpaths定义了从当前页面中XPath匹配的区域提取链接,其值是XPath表达式或XPath表达式列表。restrict_css定义了从当前页面中CSS选择器匹配的区域提取链接,其值是CSS选择器或CSS选择器列表。还有一些其他参数代表了提取链接的标签、是否去重、链接的处理等内容,使用的频率不高。可以参考文档的参数说明:http://scrapy.readthedocs.io/en/latest/topics/link-extractors.html#module-scrapy.linkextractors.lxmlhtml。

callback:即回调函数,和之前定义Request的callback有相同的意义。每次从link_extractor中获取到链接时,该函数将会调用。该回调函数接收一个response作为其第一个参数,并返回一个包含Item或Request对象的列表。注意,避免使用parse()作为回调函数。由于CrawlSpider使用parse()方法来实现其逻辑,如果parse()方法覆盖了,CrawlSpider将会运行失败。

cb_kwargs:字典,它包含传递给回调函数的参数。

follow:布尔值,即True或False,它指定根据该规则从response提取的链接是否需要跟进。如果callback参数为None,follow默认设置为True,否则默认为False。

process_links:指定处理函数,从link_extractor中获取到链接列表时,该函数将会调用,它主要用于过滤。

process_request:同样是指定处理函数,根据该Rule提取到每个Request时,该函数都会调用,对Request进行处理。该函数必须返回Request或者None。

以上内容便是CrawlSpider中的核心Rule的基本用法。下面我们利用CrawlSpider实现百度手机助手的爬取实例,来更好地理解Rule的用法。

3.具体实现 3.1 创建scrapy项目

? 首先请确认上述使用环境已经正确安装

# 1.创建项目 scrapy startproject app_spider # 2.创建爬虫 cd app_spider scrapy genspider baidu -t crawl ·

3.2 爬取链接

https://shouji.baidu.com/software/

? 打开上述链接,首页如下图所示,可以观察到app被分为十个大类,分别是:社交通讯、系统工具、理财购物…

3.3 Rule规则提取分类链接

? 查看网页源码,可以发现有十个li标签,其中每一个标签代表一个类,每一个li标签中包含了这个类的详情链接,这里定义一个rule提取这十个链接。

Rule(LinkExtractor(allow=r'/software/\d+/', restrict_xpaths=('//*[@id="doc"]/ul')), callback='parse_item', follow=True),

? 我相信根据第二节的介绍,你应该可以看懂这个rule的定义方法

3.4 Rule规则提取页码链接

? 我们随便点进去一个链接,这里以社交通讯为例,点进去,下面有一个页码链接,如下图红色方框所示,可以发现社交通讯类一共有8页,这里载设计一个rule提取每一个类的页码链接如下:

Rule(LinkExtractor(allow=r'list_\d+.html', restrict_xpaths=('//*[@id="doc"]/div[3]/div[2]/ul')), callback='parse_item', follow=True),

3.5 Rule提取每一页的app链接

? 打开每一页的源码可以发现,每一页有36个app,对应36个li标签,且app的详情链接也都在li标签中,所以再定义一个Rule提取36个li标签中app的详情链接。

Rule(LinkExtractor(allow=r'/software/\d+.html', restrict_xpaths=('//*[@id="doc"]/div[3]/div[1]/div/ul')), callback='parse_detail', follow=True),

3.6 提取app详情页面的信息

? 每一个app的详情页面如上图所示,可以提取的信息有:app名称、安装包大小、版本号、下载次数、应用介绍、小图标的链接、安装包下载链接等;

? 在items.py定义一个容器,如下所示:

class BaiDuItem(scrapy.Item): app_name = Field() version = Field() size = Field() download_num = Field() introduction = Field() file_urls = Field() image_urls = Field()

? 然后在爬虫里面定义一个parse_detail函数提取信息,这里使用xpath提取数据,如下所示:

3.7 将数据存储到mongodb数据库

? 在pipelines.py中定义一个管道,用来处理提交给管道的item信息,即把数据存储到mongodb数据库。

这里定义一个MongoPipeline类,如下所示:

class MongoPipeline(object): def __init__(self, mongo_uri, mongo_db): # MongoDB的ip和数据库名 self.mongo_uri = mongo_uri self.mongo_db = mongo_db self.conn = Redis(host='127.0.0.1', port=6379, db=0, password=123) # 借助from_crawler实现在初始化之前对settings参数调用 @classmethod def from_crawler(cls, crawler): return cls( mongo_uri=crawler.settings.get('MONGO_URI'), mongo_db=crawler.settings.get('MONGO_DB') ) def open_spider(self, spider): self.client = pymongo.MongoClient(self.mongo_uri) self.db = self.client[self.mongo_db] def process_item(self, item, spider): name = item.__class__.__name__ self.db[name].insert(dict(item)) return item def close_spider(self, spider): self.client.close()

? 同时在settings.py中定义mongo数据库配置信息和开启下载管道MongoPipeline:

MONGO_URI = 'localhost' MONGO_DB = 'app_spider' ROBOTSTXT_OBEY = False ITEM_PIPELINES = { 'app_spider.pipelines.MongoPipeline': 300, } 4.结果展示

? 打开terminal终端,输入scrapy crawl baidu ? 运行效果如下: ? 查看mongo数据库信息,大概爬取了两千多条信息,部分信息如下所示:

5.附源码

码云地址:https://gitee.com/als-sunshine-y/baidu1.git

可直接下载源码,解压后pycharm打开,终端输入:

scrapy crawl baidu

即可成功运行代码!如果运行成功的话,别忘了给博主点赞关注哈


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #38scrapy