写在开头
第一次接触scrapy,想找个简单的页面尝试下,后来在网上找到了这篇文http://blog.youkuaiyun.com/hk2291976/article/details/51227354
,感觉挺适合入门的。本人的开发环境是win10 64bit +python3.5.2 64bit,在学习的时候遇到了很多问题,所以才想起来写成文章,加深一下记忆。
首先,在安装scrapy框架的时候就遇到了很多坑。
直接用pip install scrapy
发现一直报错。。
后来百度,google了半天,发现少了以下依赖库,这里只列出文件名:
lxml-3.6.4-cp35-cp35m-win_amd64.whl
Twisted-16.5.0-cp35-cp35m-win_amd64.whl
incremental-16.10.1-py2.py3-none-any.whl
我这里大概安装了这三个
安装好以后就可以按装scrapy了:
pip install scrapy -i https://pypi.douban.com/simple
安装好以后会自动添加环境变量,下面就可以开始学习怎么使用了。
建立第一个scrapy工程
scrapy startproject doubanbook
然后你的目录下就有一个文件夹名为doubanbook目录,按照提示,我们cd进目录,然后按提示输入,这里我们爬虫取名为dbbook,网址就是上面的网址
打开pycharm,新建打开这个文件夹
输入
- 1
- 2
如图
然后我们进入spider-dbbook,然后把start_urls里面重复的部分删除(这里的会在输入的https前面又加上http://,把这部分要删除)然后把allowed_domains注掉
并且,把parse里面改成
好了,到此第一个爬虫的框架就搭完了,我们运行一下代码。(注意这里选择main.py)class DbbookSpider(scrapy.Spider): name = "dbbook" #allowed_domains = ["https://www.douban.com/doulist/1264675/"] start_urls = ['https://www.douban.com/doulist/1264675/'] def parse(self, response): print(response.body.decode()) //这里要用decode解码一下,不然看到的都是utf-8编码,教程里没有这么做
然后在settings.py里加入如下内容就可以模拟浏览器了,这里一定要加上,不然没有输出内容
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'
我们再运行,发现网页内容已经被爬取下来了
编写xpath提取标题名和作者名
这里我们就要得分,标题名和作者名
观察网页源代码,用f12,我们可以快速找到,这部分可以略过,可以借助工具生成

提取书大框架:
'//div[@class="bd doulist-subject"]'
提取题目:
'div[@class="title"]/a/text()'
提取得分:
'div[@class="rating"]/span[@class="rating_nums"]/text()'
提取作者:(这里用正则方便点)
'<div class="abstract">(.*?)<br'
编写代码
def parse(self, response): #print(response.body.decode()) item = DoubanbookItem() selector = response.selector books = selector.xpath('//div[@class="bd doulist-subject"]') for each in books: title = each.xpath('div[@class="title"]/a/text()').extract()[0] rate = each.xpath('div[@class="rating"]/span[@class="rating_nums"]/text()').extract()[0] author = re.search('<div class="abstract">(.*?)<br', each.extract(), re.S).group(1) print('标题:' + title) print('评分:' + rate) print(author) print('')
- xpath如果要提取内容,需要在后面加上.extract()
我们看看结果,不好看,对于注重美观的我们来说,简直不能忍

print('标题:' + title.strip()) print('评分:' + rate) print(author.strip()) print('')结果就是我们想要的了

items.py
好了,我们终于要讲里面别的.py文件了,关于这个items.py,你只要考虑它就是一个存储数据的容器,可以考虑成一个结构体,你所有需要提取的信息都在这里面存着。
这里我们需要存储3个变量,title,rate,author,所以我在里面加入三个变量,就这么简单:
class DoubanbookItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() title = scrapy.Field() rate = scrapy.Field() author = scrapy.Field() pass这里挺简单的,哈哈
pipelines.py
一般来说,如果你要操作数据库什么的,需要在这里处理items,这里有个process_item的函数,你可以把items写入数据库,但是今天我们用不到数据库,scrapy自带了一个很好的功能就是Feed exports,它支持多种格式的自动输出。所以我们直接用这个就好了,pipelines维持不变
settings.py
Feed 输出需要2个环境变量:
然后对 dbbook.py修改FEED_FORMAT :指示输出格式,csv/xml/json/
FEED_URI : 指示输出位置,可以是本地,也可以是FTP服务器
其实也就加了3条命令,是把数据写入item
def parse(self, response): print(response.body.decode()) return item = DoubanbookItem() selector = response.selector books = selector.xpath('//div[@class="bd doulist-subject"]') print('*'*10) for each in books: title = each.xpath('div[@class="title"]/a/text()').extract()[0] rate = each.xpath('div[@class="rating"]/span[@class="rating_nums"]/text()').extract()[0] author = re.search('<div class="abstract">(.*?)<br', each.extract(), re.S).group(1) #print('标题:' + title.strip()) #print('评分:' + rate) #print(author.strip()) #print('') item['title'] = title.strip() item['rate'] = rate item['author'] = author.strip()
因为只有这里会出现标签,所以用xpath轻松提取
'//span[@class="next"]/link/@href'
def parse(self, response): print(response.body.decode()) return item = DoubanbookItem() selector = response.selector books = selector.xpath('//div[@class="bd doulist-subject"]') print('*'*10) for each in books: title = each.xpath('div[@class="title"]/a/text()').extract()[0] rate = each.xpath('div[@class="rating"]/span[@class="rating_nums"]/text()').extract()[0] author = re.search('<div class="abstract">(.*?)<br', each.extract(), re.S).group(1) #print('标题:' + title.strip()) #print('评分:' + rate) #print(author.strip()) #print('') item['title'] = title.strip() item['rate'] = rate item['author'] = author.strip() yield item
当然,你要使用item,需要把item类引入
- 1
下面的yield可以让scrapy自动去处理item
好拉,再运行一下,可以看见D盘出现了一个douban.csv的文件
打开看一下
恰好是我们想要的结果
下面就是分页处理了
爬取剩下页面
这还只保存了一个页面,那剩下的页面怎么办呢?难道要一个个复制网址??当然不是,我们重新观察网页,可以发现有个后页的链接,里面包含着后一页的网页链接,我们把它提取出来就行了。

因为只有这里会出现标签,所以用xpath轻松提取
'//span[@class="next"]/link/@href'
def parse(self, response): print(response.body.decode()) return item = DoubanbookItem() selector = response.selector books = selector.xpath('//div[@class="bd doulist-subject"]') print('*'*10) for each in books: title = each.xpath('div[@class="title"]/a/text()').extract()[0] rate = each.xpath('div[@class="rating"]/span[@class="rating_nums"]/text()').extract()[0] author = re.search('<div class="abstract">(.*?)<br', each.extract(), re.S).group(1) #print('标题:' + title.strip()) #print('评分:' + rate) #print(author.strip()) #print('') item['title'] = title.strip() item['rate'] = rate item['author'] = author.strip() yield item nextPage = selector.xpath('//span[@class="next"]/link/@href').extract() if nextPage: next = nextPage[0] print(next) yield scrapy.http.Request(next, callback=self.parse)这里要加一个判断,因为在最后一页,“后一页”的链接就没了。
好了,我们再运行一下(先把之前的csv删除,不然就直接在后面添加了)可以发现,运行的特别快,十几页一下就运行完了,如果你用requests自己编写的代码,可以比较一下,用scrapy快很多,而且是自动化程度高很多。
我们打开csv,可以看见,有345篇文章了,和豆瓣上一致。

大功告成,原作说学会了这个例子,编写一般的爬虫就so easy了。但愿如此把,其实很多东西看起都很简单,深入了发现有很多要学的东西,慢慢积累经验,希望能把python越学越好。