基于Python2.7和Scrapy, 爬取豆瓣9分榜单

本文介绍如何使用Scrapy爬虫框架快速抓取豆瓣读书9分书籍榜单的数据,并解析页面内容,提取书名、评分和作者等信息,最终将数据保存为CSV格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

        现在scrapy的安装教程都明显过时了,随便一搜都是要你安装一大堆的依赖,什么装python(如果别人连python都没装,为什么要学scrapy....)wisted, zope interface,pywin32.........现在scrapy的安装真的很简单的好不好!

        代码我放github上了,可以参考:
        https://github.com/hk029/doubanbook

为什么要用scrapy

        我之前讲过了requests,也用它做了点东西,(【图文详解】python爬虫实战——5分钟做个图片自动下载器)感觉它就挺好用的呀,那为什么我还要用scrapy呢?

        因为:它!更!好!用!就这么简单,你只要知道这个就行了。

        我相信所有能找到这篇文章的人多多少少了解了scrapy,我再copy一下它的特点来没太多意义,因为我也不会在这篇文章内深入提。就像你知道系统的sort函数肯定比你自己编的快排好用就行了,如果需要知道为什么它更好,你可以更深入的去看代码,但这里,你只要知道这个爬虫框架别人就专门做这件事的,肯定好用,你只要会用就行。

        我希望每个来这里的人,或者每个在找资料的朋友,都能明确自己的目的,我也尽量将文章的标题取的更加的明确。如果这是一篇标题为《快速上手》的文章,那你可能就不要太抱希望于能在这篇文章里找到有关scrapy架构和实现原理类的内容。如果是那样,我可能会取标题为《深入理解scrapy》

        好了废话说了那么多,我们就上手把?

安装scrapy

  1. 下载对应版本的pywin32
     
    1. https://sourceforge.net/projects/pywin32/files/pywin32/
     
    1. python version 2.7 required,which was not found in the registry解决方案
    2.  
    3. 随便在一个盘下 新建register.py的文件,内容如下:
     
    1. #
    2. # script to register Python 2.0 or later for use with win32all
    3. # and other extensions that require Python registry settings
    4. #
    5. # written by Joakim Loew for Secret Labs AB / PythonWare
    6. #
    7. # source:
    8. # http://www.pythonware.com/products/works/articles/regpy20.htm
    9. #
    10. # modified by Valentine Gogichashvili as described in http://www.mail-archive.com/distutils-sig@python.org/msg10512.html
    11.  
    12. import sys
    13.  
    14. from _winreg import *
    15.  
    16. # tweak as necessary
    17. version = sys.version[:3]
    18. installpath = sys.prefix
    19.  
    20. regpath = "SOFTWARE\\Python\\Pythoncore\\%s\\" % (version)
    21. installkey = "InstallPath"
    22. pythonkey = "PythonPath"
    23. pythonpath = "%s;%s\\Lib\\;%s\\DLLs\\" % (
    24. installpath, installpath, installpath
    25. )
    26.  
    27. def RegisterPy():
    28. try:
    29. reg = OpenKey(HKEY_CURRENT_USER, regpath)
    30. except EnvironmentError as e:
    31. try:
    32. reg = CreateKey(HKEY_CURRENT_USER, regpath)
    33. SetValue(reg, installkey, REG_SZ, installpath)
    34. SetValue(reg, pythonkey, REG_SZ, pythonpath)
    35. CloseKey(reg)
    36. except:
    37. print "*** Unable to register!"
    38. return
    39. print "--- Python", version, "is now registered!"
    40. return
    41. if (QueryValue(reg, installkey) == installpath and
    42. QueryValue(reg, pythonkey) == pythonpath):
    43. CloseKey(reg)
    44. print "=== Python", version, "is already registered!"
    45. return
    46. CloseKey(reg)
    47. print "*** Unable to register!"
    48. print "*** You probably have another Python installation!"
    49.  
    50. if __name__ == "__main__":
    51. RegisterPy()
     
    1. 然后执行此文件
  2.     安装scrapy
     
    1. pip install scrapy

     

  3.  验证scrapy是否安装成功
     
    1. 输入 Scrapy
    2.  
    3. 如果提示如下命令,就证明安装成功啦,如果失败了,请检查上述步骤有何疏漏。
     

     

     

豆瓣读书9分书榜单爬取

我们考虑下做一个什么爬虫呢?简单点,我们做一个豆瓣读书9分书:
https://www.douban.com/doulist/1264675/

建立第一个scrapy工程

把scrapy命令的目录加入环境变量,然后输入一条命令

 
  1. scrapy startproject doubanbook

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

 

 
  1. You can start your first spider with:
  2. cd doubanbook
  3. scrapy genspider example example.com

 

 

 

打开pycharm,新建打开这个文件夹

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

输入

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

 

然后我们进入spiders目录下的dbbook.py文件【没有则新建】,然后把start_urls里面重复的部分删除(如果你一开始在命令行输入网址的时候,没输入http://www.那就不用改动)然后把allowed_domains注掉
并且,把parse里面改成

print response.body

完整内容如下:

 
  1. # -*- coding: utf-8 -*-
  2. import scrapy
  3.  
  4.  
  5.  
  6. class DbbookSpider(scrapy.Spider):
  7. name = "dbbook"
  8. # allowed_domains = ["https://www.douban.com/doulist/1264675/"]
  9. start_urls = (
  10. 'https://www.douban.com/doulist/1264675/',
  11. )
  12.  
  13. def parse(self, response):
  14. print response.body

 

 

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

运行一下,发现没打印东西,看看,原来是403

 

说明爬虫被屏蔽了,这里要加一个请求头部,模拟浏览器登录

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

 

 
  1. # Crawl responsibly by identifying yourself (and your website) on the user-agent
  2. # 加一个请求头部,模拟浏览器登录
  3. USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'

 

我们再运行,发现网页内容已经被爬取下来了

 

好了,我们的scrapy教程结束!

如果真这样结束,我知道你会打我。。

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

这里我们就要得分,标题名和作者名
观察网页源代码,用f12,我们可以快速找到,这里不细讲怎么找信息的过程了,具体过程,参考上一个教程【图文详解】python爬虫实战——5分钟做个图片自动下载器

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

 

 
  1. Xpath语法分析:
  2.  
  3. //定位根节点
  4. /往下层寻找
  5. 提取文本内容: /text()
  6. 提取属性内容: /@xxxx
 
  1. 正则表达式的符号与方法
  2.  
  3. 常用符号:点号,星号,问号与括号(小括号)
  4.  
  5. . :匹配任意字符,换行符\n除外
  6. * :匹配前一个字符0次或无限次
  7. ? :匹配前一个字符0次或1
  8. .* :贪心算法
  9. .*? :非贪心算法
  10. () :括号内的数据作为结果返回
  11. 常用方法:findall search sub
  12.  
  13. findall:匹配所有符合规律的内容,返回包含结果的列表
  14. search:匹配并提取第一个规律的内容,返回一个正则表达式对象(object)
  15. sub:替换符合规律的内容,返回替换后的值

 

 

提取书大框架:

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

提取题目:

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

提取得分:

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

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

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

编写代码

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

        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(),略为不适应,但是习惯还好。

 

我们看看结果,不好看,对于注重美观的我们来说,简直不能忍

加入两条代码:

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

再看看结果,这才是我们想要的嘛

 

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

items.py

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

这里我们需要存储3个变量,title,rate,author,所以我在里面加入三个变量,就这么简单

 

  1. # -*- coding: utf-8 -*-
  2.  
  3. # Define here the models for your scraped items
  4. #
  5. # See documentation in:
  6. # http://doc.scrapy.org/en/latest/topics/items.html
  7.  
  8. import scrapy
  9.  
  10.  
  11. classDoubanbookItem(scrapy.Item):
  12. # define the fields for your item here like:
  13. # name = scrapy.Field()
  14. title= scrapy.Field()
  15. rate= scrapy.Field()
  16. author= scrapy.Field()

 

 

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:///G://douban.csv'
FEED_FORMAT = 'CSV'

FEED_URI改成自己的就行了

dbbook.py修改

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

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

from doubanbook.items import DoubanbookItem
 
# -*- coding: utf-8 -*- import re import scrapy 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/', ) URL = 'https://www.douban.com/doulist/1264675/?start=PAGE&sort=seq&sub_type='   def parse(self, response): # print response.body  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] 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) title = title.replace(' ', '').replace('\n', '') author = author.replace(' ', '').replace('\n', '') item['title'] = title item['rate'] = rate item['author'] = author # print 'title:' + title  # print 'rate:' + rate  # print 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) 

 

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

 

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

爬取剩下页面

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

因为只有这里会出现<span class = 'next'>标签,所以用xpath轻松提取

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

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

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

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

改后的代码这样:

这里要加一个判断,因为在最后一页,“后一页”的链接就没了

好了,我们再运行一下(先把之前的csv删除,不然就直接在后面添加了)可以发现,运行的特别快,十几页一下就运行完了,如果你用requests自己编写的代码,可以比较一下,用scrapy快很多,而且是自动化程度高很多。

我们打开csv,可以看见,有345篇文章了,和豆瓣上一致。

好了,这个豆瓣9分图书的爬虫结束了,相信通过这个例子,scrapy也差不多能上手,至少编写一般的爬虫是so easy了!

目前,我们已经能对付大多数网页的内容了,现在爬本小说啥的应该都轻轻松松了,但是为什么我说大多数呢?因为确实还有一些网页我们应付不来,就是用Ajax动态加载的网页,这怎么办呢?且听下回分解:
【图文详解】scrapy爬虫与Ajax动态页面——爬取拉勾网职位信息(1)

代码我放github上了,可以参考:
https://github.com/hk029/doubanbook

参考: http://www.jianshu.com/p/fa614bea98eb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值