安装
我是pip3 install Scrapy
一梭子完事,但是看文档貌似还要搞搞xcode…
可以参考官方文档Scrapy安装指南
初始化项目
1 | scrapy startproject douban_book |
scrapy会自动初始化一个目录,里面有一些必须的文件,其结构如下:1
2
3
4
5
6
7
8
9
10
11.
├── README.md
├── __init__.py
├── __pycache__
├── items.py
├── middlewares.py
├── pipelines.py
├── settings.py
└── spiders
├── __init__.py
└── __pycache__
- scrapy.cfg: 项目的配置文件
- items.py: 项目的目标文件
- pipelines.py: 项目的管道文件
- settings.py: 项目的设置文件
- spiders: 爬虫代码目录
构建项目
定义数据
首先我们需要定义我们想要抓取什么数据,编辑item.py
,Item定义结构化数据字段,用来保存爬取到的数据,有点像Python中的dict,但是提供了一些额外的保护减少错误。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class DoubanBookItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() #书名
link = scrapy.Field() #链接
author = scrapy.Field() #作者
score = scrapy.Field() #评分
scoreNum = scrapy.Field() #评论人数
press = scrapy.Field() #出版社
isbn = scrapy.Field() #isbn
price = scrapy.Field() #价格
publishyear = scrapy.Field() #出版年
authordesc = scrapy.Field() #作者简介
bookdesc = scrapy.Field() #书简介
label = scrapy.Field() #标签
pagecount = scrapy.Field() #字数
imgurl = scrapy.Field() #图片链接
编写爬虫
爬数据
我们需要用scrapy.Spider类创建一个子类,并为其确定三个强制的属性。
- name = “” :这个爬虫的识别名称,必须是唯一的,在不同的爬虫必须定义不同的名字。
- allow_domains = [] 是搜索的域名范围,也就是爬虫的约束区域,规定爬虫只爬取这个域名下的网页,不存在的URL会被忽略
- start_urls = () :爬取的URL元祖/列表。爬虫从这里开始抓取数据,并根据子url继续往下爬。
1 | name = "douban_book" |
取数据
parse()方法解析数据,这里运用了XPATH
,虽然以前用的BeautifulSoup4
,不过都是解析啦 这个问题不大。
chrome浏览器提供检查->选中元素->copy->XPATH的快捷方式获取这个,我写的时候一边写一边测试的。1
2
3
4#举个栗子
title = response.xpath("//div[@id='wrapper']/h1/span/text()").extract()
link = response.url
imgurl = response.xpath("//div[@id='mainpic']/a[@class='nbg']/@href").extract_first()
存储数据
现在我们已经获取我们想要的数据了,下一步就是把他们存下来,可以存成csv文件,或者直接存到数据库里。这里选择保存到MySQL。
在pipelines.py里定义process_item()
方法,在这里可以对数据做一定的处理,比如缺失值异常值之类的,然后存入数据库。
1 | def process_item(self, item, spider): |
最终结果如下:1
2
3
4
5
6
7
8
9
10
11 id: 75
title: 沉默的大多数
author: 王小波
score: 9.1
scorenum: 0
press: 中国青年出版社
isbn: 9787500627098
price: 27.0000
publishyear: 1997-10
label: 王小波,杂文,沉默的大多数,思想,随笔,中国文学,文学,中国
pagecount: 555
ToDo
- 页面解析并不是很好,经常缺数据
- 加入redis
- 会被封IP,需要加ip池