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

本文通过实例介绍如何使用Scrapy框架进行网页爬取,包括安装配置、数据抓取及存储等核心步骤。

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

写在开头

第一次接触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,新建打开这个文件夹

打开后,我们在最顶层的目录上新建一个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的位置吗?就是那里,那里就是我们要对数据处理的地方。我们写好代码,这里注意:
  1. 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越学越好。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值