项目介绍
使用Scrapy框架进行爬取伯乐在线的所有技术文章
所用知识点
- Scrapy项目的创建
- Scrapy框架Shell命令的使用
- Scrapy自带的图片下载管道
- Scrapy自定义图片下载管道(继承自带的管道)
- Scrapy框架ItemLoader的使用
- Scrapy自定义ItemLoader
- Scrapy中同步将Item保存入Mysq数据库
- Scrapy中异步将Item保存入Mysq数据库
项目初始
创建新项目
scrapy startproject bole
创建爬虫
scrapy genspider jobbole blog.jobbole.com
爬虫调试
为了方便对爬虫进行调试,在项目目录中创建一个main.py文件
|
|
在爬虫开始运行时,建议修改项目中的配置文件,找到
前置知识
XPath语法简介
表达式 | 说明 | |
---|---|---|
article | 选取所有article元素的所有子节点 | |
/article | 选取根元素article | |
article/a | 选取所有属于article的子元素的a元素 | |
article/a/text() | 选取所有属于article的子元素的a元素中的文本内容 | |
//div | 选取所有div子元素(无论出现在文档的任何地方) | |
//@class | 选取所有名为class的属性 | |
/article/div[1] | 选取article子元素的第一个div元素 | |
/article/div[last()] | 选取article子元素的最后一个div元素 | |
/article/div[last()-1] | 选取article子元素的最后第二个div元素 | |
//div[@lang] | 选取所有拥有lang属性的div元素 | |
//div[@lang=’eng’] | 选取所有lang属性为eng的div元素 | |
/div/* | 选取属于div元素下的所有子节点 | |
//* | 选取所有元素 | |
//div[@*] | 选取所有带有属性的div元素 | |
//div/a \ | //div/p | 选取所有div元素下的a和p元素 |
//spand \ | //ul | 选取文档中的span和ul元素 |
article/div/p \ | //span | 选取所有属于article元素的div元素的p元素以及文档中所有span元素 |
CSS常用选择器
表达式 | 说明 |
---|---|
* | 选择所有节点 |
#container | 选择id为container的节点 |
.container | 选择所有class中包含container的节点 |
li a | 选择所有li下面的所有a节点 |
ul + p | 选择ul后面的第一个p元素 |
div#container > ul | 选择id为container的div节点下的第一个ul节点 |
ul ~ p | 选择与ul相邻的所有p元素 |
a[title] | 选择所有包含title属性的a元素 |
a::text | 获得所有a元素的文本内容 |
a[href=”www.baidu.com”] | 选择所有href属性值为www.baidu.com的a元素 |
a[href*=”baidu”] | 选择所有href属性值包含baidu的a元素 |
a[href^=”www”] | 选择所有href属性值以www开头的a元素 |
a[href$=”.jpg”] | 选择所有href属性值以.jpg结尾的a元素 |
input[type=radio]:checked] | 选择所有选中的radio |
div:not(#container) | 选择所有id不为container的div元素 |
li:nth-child(2) | 选择第二个li元素 |
li:nth-child(2n) | 选择第偶数的li元素 |
Scrapy shell模式
在解析页面的时候如果要查看运行结果则必须要运行Scrapy爬虫发起一个请求,而Scrapy提供了一种方便的调试方法可以只请求一次。
shell 网址```
12345 例如```shellscrpay shell http://blog.jobbole.com/111144/
文章解析
文章详情页
Xpath的解析方式
|
|
CSS解析方式
CSS解析的方式使代码更加的简短和明了,因此采用CSS选择器是个较好的选择
|
|
列表页
解析完成详情页后,我们要解析列表页获得每一篇文章的url和封面图,然后再交给parse_detail函数去解析
|
|
定义Items
|
|
pipeline管道的使用
Scrapy自带的图片下载管道
在settings.py中的pipeline处添加 scrapy.pipeline.images.ImagesPipeline
|
|
之后运行项目可能包PIL未找到,因此需要
install pillow```
1 > 此外scrapy的图片下载默认是接受一个数组,因此在赋值的时候需要```article_item["font_image_url"] = [font_image_url]
自定义图片下载管道
虽然Scrapy自带的下载中间件很好用,但是如果我要获取图片下载后保存的路径则官方自带就不能满足需求,因此需要我们自定义管道
|
|
使用Scrapy自带的管道将Item导出成Json文件
|
|
自定义管道将Item保存为Json文件
|
|
同步化将Item保存入数据库
pip install mysqlclient 安装Mysql客户端库
|
|
异步化将Item保存入数据库
因为Scrapy的解析速度非常快,加上文章的内容较大,因此会出现数据库的操作速度赶不上解析速度会产生阻塞,因此采用异步化的方式来进行数据的插入
|
|
项目改进
前面使用了最基本的方式来解析的文章详情页,这样使得spider的代码十分长,不容易维护,因此可以采用自定义ItemLoder的方式方便对规则的管理
spider文件的修改
|
|
自定义的ItemLoader
|
|