您的位置:首页 > 编程语言 > Python开发

scrapy入门学习笔记之爬取豆瓣9分榜单

2016-11-06 16:02 232 查看
写在开头

第一次接触scrapy,想找个简单的页面尝试下,后来在网上找到了这篇文http://blog.csdn.net/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,新建打开这个文件夹

打开后,我们在最顶层的目录上新建一个python文件,取名为main,这是运行的主程序(其实就一行代码,运行爬虫)

输入
from scrapy import cmdline
cmdline.execute("scrapy crawl dbbook".split())
1
2



如图



然后我们进入spider-dbbook,然后把start_urls里面重复的部分删除(这里的会在输入的https前面又加上http://,把这部分要删除)然后把allowed_domains注掉 

并且,把parse里面改成
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编码,教程里没有这么做

好了,到此第一个爬虫的框架就搭完了,我们运行一下代码。(注意这里选择main.py)

然后在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('')


关键这个代码在哪里编写呢?答案就是还记得大明湖……不对,是还记得刚才输出response的位置吗?就是那里,那里就是我们要对数据处理的地方。我们写好代码,这里注意:

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个环境变量:

FEED_FORMAT :指示输出格式,csv/xml/json/ 

FEED_URI : 指示输出位置,可以是本地,也可以是FTP服务器

FEED_URI = u'file:///D://douban.csv'
FEED_FORMAT = 'CSV'

然后对dbbook.py修改

其实也就加了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类引入
from doubanbook.items import DoubanbookItem
1

下面的yield可以让scrapy自动去处理item

好拉,再运行一下,可以看见D盘出现了一个douban.csv的文件

打开看一下



恰好是我们想要的结果

下面就是分页处理了


爬取剩下页面

这还只保存了一个页面,那剩下的页面怎么办呢?难道要一个个复制网址??当然不是,我们重新观察网页,可以发现有个后页的链接,里面包含着后一页的网页链接,我们把它提取出来就行了。 



因为只有这里会出现标签,所以用xpath轻松提取
'//span[@class="next"]/link/@href'


然后提取后 我们scrapy的爬虫怎么处理呢? 

答案还是yield,
yield scrapy.http.Request(url,callback=self.parse)
1



这样爬虫就会自动执行url的命令了,处理方式还是使用我们的parse函数

改后代码如下:

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越学越好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python python爬虫