Scrapy从入门到精通(4)

项目实战

url = http://books.toscrape.com

页面分析

scrapy shell U R L>
scrapy shell URL>可以使用户在交互式命令行下操作一个Scrapy,通常用来进行前期爬取实验,提高开发效率

scrapy shell http://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html

执行完成后,scrapy shell会使用url参数构造一个response对象,提交给Scrapy引擎,页面下载完成后,程序进入一个Python shell当中,此时环境中已经创建好了一些变量

  • request:最近一次下载对应的request对象
  • response:最近一次下载对应的response对象
  • fetch(req_or_url):用于下载页面,可传入一个request或url,调用后会更新变量request和response
  • view(response):用于在浏览器显示response中的页面

view(response)

执行后会在浏览器直接打开页面,但这是由Scrapy下载的页面 ,浏览器直接打开是由浏览器下载的


这里写图片描述
可以在

中提取书名、价格、评价等级,在Scrapy shell中尝试提取这些等级

这里写图片描述


分析完书籍页面后,接着分析如何在书籍列表页面中提取每一个书籍页面的链接,在Scrapy shell中,先调用fetch函数下载第一个书籍列表页面,下载后再view函数在浏览器中查看页面

fetch('http://books.toscrape.com')
view(response)

这里写图片描述


每个书籍页面都可以在每个

中找到,在scrapy shell中使用LinkExtract提取

from scrapy.linkextractors import LinkExtractor
le = LinkExtractor(restrict_css='article.product_pod')
le.extract_links(response)

编码实现

这里写图片描述

#创建项目
scrapy startproject toscrape_book

可以使用scrapy genspider name url命令生成模板

cd toscrape_book
scrape genspider books books.toscrape.comm

运行后,genspider创建文件toscrape_book/spiders/books.py,并在其中创建了一个BooksSpider类
这里写图片描述
在实现spider之前,先定义封装书籍信息Item类,在toscrape_book/items.py中添加

class BookItem(scrapy.Item):
    name = scrapy.Field()#书名
    price = scrapy.Field()
    review_rating = scrapy.Field()#评价等级
    review_num = scrapy.Field()
    upc = scrapy.Field()#产品编码
    stock = scrapy.Field()#库存量

接下来,按照一下五步完成BooksSpider

  • 继承Spider创建BooksSpider类(已完成)
  • 为spider取名(已完成)
  • 指定爬取点(已完成)
  • 实现书籍列表页面解析函数
  • 实现书籍页面解析函数
    前三部由scrapy genspider命令完成
    这里写图片描述
    完成第四步,实现列表页面解析函数parse
    parse的任务

  • 提取页面中每一个书籍页面的链接,用它们构造request对象并提交

  • 提取页面中下一个书籍列表页面的链接,用构造request对象并提交
from scrapy.linkextractors import LinkExtractor
#提取书籍列表页面中的每本书的链接
    def parse(self, response):
        le = LinkExtractor(restrict_css='article.product_pod h3')
        for link in le.extract_links(response):
            yield scrapy.Request(link.url,callback=self.parse_book)

        # 提取 下一页 的链接
        le = LinkExtractor(restrict_css='ul.pager li.next')
        links = le.extract_links(response)
        if links:
            next_url = links[0].url
            yield scrapy.Request(next_url,callback=self.parse)

最后完成书籍页面解析函数(parse_book方法)
提取书籍信息存入BookItem对象即可

 def parse_book(self,response):
        book = BookItem()
        sel = response.css('div.product_main')
        book['name'] = sel.xpath('./h1/text()').extract_first()
        book['price'] = sel.css('p.price_color::text').extract_first()
        book['review_rating'] = sel.css('p.star-rating::attr(class)')\
                                        .re_first('start-raing([A-Za-z])')

        sel =response.css('table.table.table-striped')
        book['upc'] = sel.xpath('(.//tr)[1]/td/text()').extract_first()
        book['stock'] = sel.xpath('(.//tr)[last()-1]/td/text()')\
                                    .re_first('\((\d+)available\)')
        book['review_num'] = sel.xpath('(.//tr)[last()]/td/text()').extract_first()

        yield book

books.py完整代码

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from ..items import BookItem


class BooksSpider(scrapy.Spider):
    name = 'books'
    allowed_domains = ['books.toscrape.com']
    start_urls = ['http://books.toscrape.com/']

#书籍列表页面的解析函数
    #提取书籍列表页面中的每本书的链接
    def parse(self, response):
        le = LinkExtractor(restrict_css='article.product_pod h3')
        for link in le.extract_links(response):
            yield scrapy.Request(link.url,callback=self.parse_book)

        # 提取 下一页 的链接
        le = LinkExtractor(restrict_css='ul.pager li.next')
        links = le.extract_links(response)
        if links:
            next_url = links[0].url
            yield scrapy.Request(next_url,callback=self.parse)
#书籍页面的解析函数

    def parse_book(self,response):
        book = BookItem()
        sel = response.css('div.product_main')
        book['name'] = sel.xpath('./h1/text()').extract_first()
        book['price'] = sel.css('p.price_color::text').extract_first()
        book['review_rating'] = sel.css('p.star-rating::attr(class)')\
                                        .re_first('start-raing([A-Za-z])')

        sel =response.css('table.table.table-striped')
        book['upc'] = sel.xpath('(.//tr)[1]/td/text()').extract_first()
        book['stock'] = sel.xpath('(.//tr)[last()-1]/td/text()')\
                                    .re_first('\((\d+)available\)')
        book['review_num'] = sel.xpath('(.//tr)[last()]/td/text()').extract_first()

        yield book

启动spider

scrapy crawl books -o books.csv --nolog

整理列次序
在settings.py中使用FEED_EXPORT_FIELDS指定列次序

FEED_EXPORT_FIELDS = ['UPS','name','price','stock','review_rating','review_num']

改变评级中的 one=1
在pipelines.py中实现BookPipeline

class BookPipeline(object):
    review_rating_map = {
    'One' = 1,
    'Tow' = 2,
    'Three' = 3,
    'Four' = 4,
    'Five' = 5,
    }
    def provess_item(self,item,spider):
        rating = item.get('review_rating')
        if rating:
            item['review_rating'] = self.review_rating_map[rating]
        return item

在settings.py中配置

ITEM_PIPELINES={'toscrape_book.pipelines.BookPipeline':300,}

猜你喜欢

转载自blog.csdn.net/weixin_39381833/article/details/80925245