Scrapy学习笔记(2)

来源:互联网 发布:mac qq截图存在哪里 编辑:程序博客网 时间:2024/05/02 04:16

这一篇笔记主要介绍scrapy爬取名人名言、作者信息以及如何翻页操作,下一页!,本次要爬取的网址"http://www.dailyenglishquote.com/",上面有很多名人名言,类似于scrapy官方文档的入门例子,不过要稍微复杂一些,因为除了名字、名人名言以外,还有对它的中文解释、简略介绍作者,这网站很良心,很适合爬虫练习

废话不多说,先建一个工程
>scrapy startproject FamousQuotes
>cd FamousQuotes
>scrapy genspider quotes "www.dailyenglishquote.com"

接下来到网页去分析要爬取什么
发布的时间我们不爬,因为又不是出名言的时间。我们要爬取的有一下几项:

  • <div class="entry cf">首先,每个独立的名人名言都是这个标签,我们可以先定位这些个标签,接下来分别处理列表里的每一项:
    • 第一个a标签的title就是作者和职业:title="Les Brown (励志演说家)"
    • 第一个p标签的strong标签是英文名言:<p><strong style="color: #0b5394;">&#8220;The things you want...experience.&#8221;</strong></p>,其中&#8220;&#8221;
      是前/后双引号,这个没什么影响,可以在导出数据的时候用字符串的替换replace()即可
    • 接下来的div标签是作者的名字和英文职业,我们也可以爬下来:<div style="text-align: center; margin-top: -18px; margin-bottom: 18px;">&#8211; Les Brown, Motivational Speaker</div>
    • 第二个p标签就是中文翻译:<p>「你想要的东西一...是一个很大的障碍物。」&#8211; 莱斯‧布朗 (励志演说家)</p>
    • 接下来的ul标签中的li标签就是介绍作者了:<ul>
      <li>莱斯‧布朗 (1945- ) 出身贫寒,但他追求...促使人们超越平庸是他演讲的主轴。</li>
      </ul>
    • 什么??你说头像??好吧,我们只需要把图片地址爬下来就好,因为本地并没有很大的空间来存放,并且,如果你要利用图片,有图片链接也是可以用的。img标签就在div标签的a标签里面,爬取src属性即可

好了,以上就是我们要爬取的内容,先到scrapy shell里测试一下吧:
scrapy shell "http://www.dailyenglishquote.com/"

  1. response.xpath('//div[@class="entry cf"]')
    显示了我们要找的所有div,然后将它赋值给divs,方便下边用

  2. divs.xpath('a/@title').extract()是对应的a标签的title,然而,对于列表中的第一个结果,我醉了。。如下:
    ['英文名言', 'Lena Waithe (編劇)', 'Laurence J. Peter (哲學家)', 'Abraham
    Maslow (心理學家)', 'Amy Poehler (女演員)', 'Les Brown (勵志演說家)', 'Ale
    xis Carrel (外科醫生)']

    繁体字我就先不吐槽了,问题是第一个标题“英文名言”!我看了看后边的几页,都是正常的,也就是说只有第一页的第一个标题是英文名言。这种情况我们不要在意,因为后边还有一个div标签是英文名和职业,所以说不碍事

  3. divs.xpath('p/strong/text()').extract()是所有的英文名言,还好,没什么问题。

  4. divs.xpath('div/text()').extract()是英文名、英文职业

  5. divs.xpath('p/text()').extract()是所有的中文翻译

  6. divs.xpath('ul/li/text()').extract()是所有的作者介绍

  7. divs.xpath('div/a/img/@src').extract()就是头像

  8. 这是下一页的标签:<a class="nextpostslink" rel="next" href="http://www.dailyenglishquote.com/page/2/">»</a>所以,只需要response.xpath('//a[@rel="next"]/@href').extract_first()就好了

有了以上这些,我们就可以完成爬取了,接下来就是写quotes.py了,这是代码:

# -*- coding: utf-8 -*-import scrapyclass QuotesSpider(scrapy.Spider):    name = 'quotes'    start_urls = ['http://www.dailyenglishquote.com/']    def parse(self, response):        for div in response.xpath('//div[@class="entry cf"]'):            yield {                'title': div.xpath('a/@title').extract_first(),                'En_content': div.xpath('p/strong/text()').extract_first(),                'Name&Job': div.xpath('div/text()').extract_first(),                'Zh_content': div.xpath('p/text()').extract_first(),                'introduction': div.xpath('ul/li/text()').extract_first(),                'img_src': div.xpath('div/a/img/@src').extract_first()            }        '下面next_page就是下一页的链接'        next_page = response.xpath('//a[@rel="next"]/@href').extract_first()        if next_page is not None: # 判断是否为None类型            yield scrapy.Request(next_page, callback=self.parse) # 回调下一页

接下来我们写一下pipelines.py
记得把settings.py中
ITEM_PIPELINES = {
'FamousQuotes.pipelines.FamousquotesPipeline': 300,
}

这项取消注释
一下是pipelines.py的代码:

import jsonclass FamousquotesPipeline(object):    def open_spider(self, spider):        self.file = open('items.jl', 'w', encoding='utf-8')    def close_spider(self, spider):        self.file.close()    def process_item(self, item, spider):        line = json.dumps(dict(item), ensure_ascii=False) + '\n'        self.file.write(line)        return item

以上就是全部代码,在pipelines.py中的open_spider里面,如果open里的encoding不是gbk系列或者utf-8的话会报错,UnicodeEncodeError: 'gbk' codec can't encode character '\u2027' in position,编码问题到处都是~~~