logo头像

一路过来,不过游牧自己。。

爬虫实战之爬取豆瓣9分榜单


额,首先声明我是安装好了Scrapy的,然后主要是用工具pycharm去编写代码,为什么要写这个豆瓣这个呢,因为觉得很有代表性,对入门非常有启发!

一、豆瓣读书9分书榜单爬取

爬取得网站地址下:(https://www.douban.com/doulist/1264675)
首先要在命令行创建一个scrapy工程:

1
scrapy startproject doubanbook

然后你的目录下就有一个文件夹为doubanbook目录,按照提示,我们cd进目录,然后按提示输入,这里我们爬虫取名为dbbook,网址就是上面的网址:

1
scrapy genspider dbbook https://www.douban.com/doulist/1264675/

然后打开pycharm,新建打开这个文件夹工程,这个如何打开就自己去搜吧!
打开后,我们在最顶层的目录上新建一个python文件,取名为main,这是运行的主程序(其实就一行代码,运行爬虫)
输入:

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

然后我们进入spider-dbbook,然后把start_urls里面重复的部分删除(如果你一开始在命令行输入网址的时候,没输入http://www.那就不用改动)然后把allowed_domains注掉
并且,把parse里面改成

1
print response.body

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

运行一下,发现没打印东西,看看,原来是403
403
说明爬虫被屏蔽了,这里要加一个请求头部,模拟浏览器登录

在settings.py里加入如下内容就可以模拟浏览器了

1
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'

我们再运行,发现网页内容已经被爬取下来了,已经有了网页信息!
但这样没用啊,我们要的不是这些!

二、编写xpath提取标题名和作者名

这里我们就要得分,标题名和作者名
观察网页源代码,用f12,我们可以快速找到,这里不细讲怎么找信息的过程了,或者直接右键检查就行!

根据先大后小的原则,我们先用bd doulist-subject,把每个书找到,然后,循环对里面的信息进行提取

提取书大框架:

1
'//div[@class="bd doulist-subject"]'

提取题目:

1
'div[@class="title"]/a/text()'

提取得分:

1
'div[@class="rating"]/span[@class="rating_nums"]/text()'

提取作者:(这里用正则方便点)

1
'<div class="abstract">(.*?)<br'

三、编写代码

经过之前的学习,应该很容易写出下面的代码吧:作者那里用正则更方便提取

1
2
3
4
5
6
7
8
9
10
selector = scrapy.Selector(response)
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的位置,那里就是我们要对数据处理的地方。我们写好代码,这里注意:
1、不是用etree来提取了,改为scrapy.Selector了
2、xpath如果要提取内容,需要在后面加上.extract(),略为不适应,但是习惯还好。
我们看看结果,结果不好看,简直不能忍!

加入两条代码美化下:

1
2
title = title.replace(' ','').replace('\n','')
author = author.replace(' ','').replace('\n','')

这就美观多了!
好了,剩下的事情就是如何把结果写入文件或数据库了,这里我采用写入文件,因为如果是写入数据库,我又得花时间讲数据库的一些基本知识和操作,还是放在以后再说吧。

四、存储

items.py

好了,我们终于要讲里面别的.py文件了,关于这个items.py,你只要考虑它就是一个存储数据的容器,可以考虑成一个结构体,你所有需要提取的信息都在这里面存着。
这里我们需要存储3个变量,title,rate,author,所以我在里面加入三个变量,就这么简单:

1
2
3
title = scrapy.Field()
rate = scrapy.Field()
author = scrapy.Field()

pipelines.py

一般来说,如果你要操作数据库什么的,需要在这里处理items,这里有个process_item的函数,你可以把items写入数据库,但是今天我们用不到数据库,scrapy自带了一个很好的功能就是Feed exports,它支持多种格式的自动输出。所以我们直接用这个就好了,pipelines维持不变

settings.py

Feed 输出需要2个环境变量:

1
2
3
4
5
FEED_FORMAT :指示输出格式,csv/xml/json/
FEED_URI : 指示输出位置,可以是本地,也可以是FTP服务器

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

FEED_URI改成自己的就行了!

dbbook.py修改

其实也就加了3条命令,是把数据写入item

当然,你要使用item,需要把item类引入

1
from doubanbook.items import DoubanbookItem

下面的yield可以让scrapy自动去处理item
好拉,再运行一下,可以看见G盘出现了一个douban.csv的文件,打开就可以看到结果了!

五、爬取剩下页面

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

因为只有这里会出现标签,所以用xpath轻松提取

1
'//span[@class="next"]/link/@href'

然后提取后 我们scrapy的爬虫怎么处理呢?
答案还是yield,

1
yield scrapy.http.Request(url,callback=self.parse)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# -*- coding: utf-8 -*-
import scrapy
import re
from doubanbook.items import DoubanbookItem


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):
item=DoubanbookItem()
selector=scrapy.Selector(response)
books=selector.xpath('//div[@class="bd doulist-subject"]')
for each in books:
title=each.xpath('div[@class="title"]/a/text()').extract()[0]
item['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)
item['title'] = title.replace(' ', '').replace('\n', '')
item['author'] = author.replace(' ', '').replace('\n', '')
# print 'title:'+title
# print 'Score:'+rate
# print 'author:'+author
#print ''
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)

这里要加一个判断,因为在最后一页,“后一页”的链接就没了。
这样就发现书目全被爬下来了!
好了,这个豆瓣9分图书的爬虫结束了,相信通过这个例子,我们已经能对付大多数网页的内容了,scrapy也差不多能上手,至少编写一般的爬虫是so easy了!

多走路,多思考,越努力,越幸运!
———————————————YoungerFary

微信打赏

赞赏是不耍流氓的鼓励