美文网首页信息组织与信息检索
数据采集练习之抓取豆瓣书籍Top250

数据采集练习之抓取豆瓣书籍Top250

作者: cathy1997 | 来源:发表于2018-05-16 22:21 被阅读239次

数据来源:

豆瓣图书 Top 250

目标描述:

建立一个爬虫项目,抓取豆瓣读书Top 250页面的250本书的信息,采集字段包括:

  • 书的图片
  • 书名
  • 作者
  • 出版社
  • 价格
  • 评分
  • 简介

开始爬虫

1.新建项目

scrapy startproject douban

进入项目

cd douban

2.编写item.py文件,定义将要爬取的字段

import scrapy

class DoubanItem(scrapy.Item):
    img = scrapy.Field() # 书的图片地址
    book_name = scrapy.Field() # 书名
    english_name = scrapy.Field() # 英文名
    author = scrapy.Field() # 作者
    publish = scrapy.Field() # 出版社
    price = scrapy.Field() # 价格
    score = scrapy.Field() # 评分
    description = scrapy.Field() # 简介 
    pass

3.创建并编写doubanspider.py文件

通过css选择路径:

# -*- coding: utf-8 -*-
import scrapy
from douban.items import DoubanItem

class DoubanspiderSpider(scrapy.Spider):
    name = 'doubanspider'
    # allowed_domains = ['https://www.douban.com/']
    start_urls = ['https://book.douban.com/top250',]

    def parse(self, response):
        for book in response.css('tr.item'):
            item = DoubanItem()
            item['img'] = book.css('a.nbg img::attr(src)').extract_first()
            item['book_name'] = book.css('div.pl2 a::attr(title)').extract()
            item['english_name'] = book.css('div.pl2 span::text').extract_first()
            item['author'] = book.css('p.pl::text').extract_first().split('/')[0]
            item['publish'] = book.css('p.pl::text').extract_first().split('/')[-3]
            item['price'] = book.css('p.pl::text').extract_first().split('/')[-1]
            item['score'] = book.css('div.star.clearfix span.rating_nums::text').extract_first()
            item['description'] = book.css('p.quote span.inq::text').extract_first()
            yield item

            next_link = response.css("div.paginator span.next a::attr(href)").extract_first() # 得到下一页网址的起始数字
            # 查看是否有下一页
            if next_link is not None:
                next_link = next_link.split('?')[-1]
                next_page = '?' + next_link
                next_page = response.urljoin(next_page)  # 生成下一页的链接
                yield scrapy.Request(next_page,callback=self.parse) # 访问下一页

通过xpath选择路径:

import scrapy
from douban.items import DoubanItem

class DoubanspiderSpider(scrapy.Spider):
    name = 'doubanspider'
    # allowed_domains = ['https://www.douban.com/']
    start_urls = ['https://book.douban.com/top250',]

    def parse(self, response):
        for book in response.xpath(".//div[@class='article']//table"):
            item = DoubanItem()
            item['img'] = book.xpath(".//a/img/@src").extract_first()
            item['book_name'] = book.xpath(".//div[@class='pl2']/a/@title").extract_first().strip()
            item['english_name'] = book.xpath(".//div[@class='pl2']/span/text()").extract()
            item['author'] = book.xpath(".//p[@class='pl']/text()").extract_first().split('/')[0]
            item['publish'] = book.xpath(".//p[@class='pl']/text()").extract_first().split('/')[-3]
            item['price'] = book.xpath(".//p[@class='pl']/text()").extract_first().split('/')[-1]
            item['score'] = book.xpath(".//span[@class='rating_nums']/text()").extract_first()
            item['description'] = book.xpath(".//p[@class='quote']/span/text()").extract_first()
            yield item

            next_link = response.xpath("..//div[@class='paginator']//span[@class='next']/a/@href") # 得到下一页网址的起始数字
            # 查看是否有下一页
            if next_link:
                next_link = next_link.extract_first().split('?')[-1]
                next_page = '?' + next_link
                next_page = response.urljoin(next_page)  # 生成下一页的链接
                yield scrapy.Request(next_page,callback=self.parse) # 访问下一页

4.开始爬虫,并保存到data.json文件

scrapy crawl doubanspider -o data.json

查看获取的数据数量,获取到250条数据。


image.png

查看json文件:


data.json

采集过程中遇到的几个问题:

问题1:使用scrapy shell查看xpath路径是否正确提取到数据时无法连接到目标网站

在命令行输入

scrapy shell "https://book.douban.com/top250"

返回结果:

返回状态码403
可以看到,申请访问豆瓣读书页面的HTTP返回状态码是403,说明豆瓣设置了反爬虫机制,会检查访问者的user-agent信息,因此个人爬虫无法抓取数据。
解决办法
1. 连接时在命令上加上 -s USER_AGENT='Mozilla/5.0',即
scrapy shell -s USER_AGENT='Mozilla/5.0' "https://book.douban.com/top250"
返回状态码200
返回状态码为200,成功访问到页面。这种方法简单但是每次操作时都要加上这段代码比较繁琐。
2. 修改scrapy的user-agent默认值
我的参考:Scrapy shell调试返回403错误 - CSDN博客
首先找到python的:安装目录下的default_settings.py文件,比如我的在D:\Program Files\python\Lib\site-packages\scrapy\settings\default_settings.py
USER_AGENT = 'Scrapy/%s (+http://scrapy.org)' % import_module('scrapy').__version__ 

改为

USER_AGENT = 'Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0' 
修改默认设置

则再次访问此类网站时,可以正常访问html不会在出现403错误了。这种修改主要是更改自己的user-agent信息,伪装成浏览器进行访问。

问题2:下一页的链接构建正确,但是无法访问下一页的链接从而无法循环采集数据

查阅各种资料后发现我的下面这行代码有误,注释掉即可:

allowed_domains = ['https://www.douban.com/'] # 包含构成许可域的基础URL,供蜘蛛去爬,不在此允许范围内的域名就会被过滤,而不会进行爬取

而我要访问的网页

https://book.douban.com/top250?start=0

是不在允许域的,因此出现错误。
需要说明的一点:虽然设置了允许域进行过滤,但是不会过滤start_urls的网址,因此首页数据可以获取到,只是无法进行循环抓取。

相关文章

网友评论

    本文标题:数据采集练习之抓取豆瓣书籍Top250

    本文链接:https://www.haomeiwen.com/subject/xrimdftx.html