资讯专栏INFORMATION COLUMN

Scrapy学习(三) 爬取豆瓣图书信息

Tony_Zby / 2399人阅读

摘要:因为暂时还没有学到如何模拟登陆,所以我就先抓像豆瓣这样不需要登陆的网站上的内容。其中会回调函数,用是因为豆瓣图书并不是格式一致的。只需要在中设置项目代码地址豆瓣图书爬虫

前言

Scrapy学习(一) 安装

Scrapy学习(二) 入门

有了前两篇的基础,就可以开始互联网上爬取我们感兴趣的信息了。因为暂时还没有学到如何模拟登陆,所以我就先抓像豆瓣这样不需要登陆的网站上的内容。
我的开发环境是 Win7 + PyChram + Python3.5 + MongoDB
爬虫的目标是豆瓣的日本文学标签下的所有书籍基本信息

创建项目

scrapy startproject douban

接着移动到douban目录下

scrapy genspider book book.douban.com

在spider目录下生成相应的BookSpider模板

编写Item

在items.py中编写我们需要的数据模型

class BookItem(scrapy.Item):
    book_name = scrapy.Field()
    book_star = scrapy.Field()
    book_pl = scrapy.Field()
    book_author = scrapy.Field()
    book_publish = scrapy.Field()
    book_date = scrapy.Field()
    book_price = scrapy.Field()
编写Spider

访问豆瓣的日本文学标签,将url的值写到start_urls中。接着在Chrome的帮助下,可以看到每本图书是在ul#subject-list > li.subject-item

class BookSpider(scrapy.Spider):
    ...
    def parse(self, response):
        sel = Selector(response)
        book_list = sel.css("#subject_list > ul > li")
        for book in book_list:
            item = BookItem()
            item["book_name"] = book.xpath("div[@class="info"]/h2/a/text()").extract()[0].strip()
            item["book_star"] = book.xpath("div[@class="info"]/div[2]/span[@class="rating_nums"]/text()").extract()[
                0].strip()
            item["book_pl"] = book.xpath("div[@class="info"]/div[2]/span[@class="pl"]/text()").extract()[0].strip()
            pub = book.xpath("div[@class="info"]/div[@class="pub"]/text()").extract()[0].strip().split("/")
            item["book_price"] = pub.pop()
            item["book_date"] = pub.pop()
            item["book_publish"] = pub.pop()
            item["book_author"] = "/".join(pub)
            yield item

测试一下代码是否有问题

scrapy crawl book -o items.json

奇怪的发现,items.json内并没有数据,后头看控制台中的DEBUG信息

2017-02-04 16:15:38 [scrapy.core.engine] INFO: Spider opened
2017-02-04 16:15:38 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2017-02-04 16:15:38 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2017-02-04 16:15:39 [scrapy.core.engine] DEBUG: Crawled (403) 2017-02-04 16:15:39 [scrapy.core.engine] DEBUG: Crawled (403)

爬取网页时状态码是403。这是因为服务器判断出爬虫程序,拒绝我们访问。
我们可以在settings中设定USER_AGENT的值,伪装成浏览器访问页面。

USER_AGENT = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"

再试一次,就发现items.json有值了。但仔细只有第一页的数据,如果我们想要爬取所有的数据,就需要爬完当前页后自动获得下一页的url,以此类推爬完所有数据。
所以我们对spider进行改造。

    ...
    def parse(self, response):
        sel = Selector(response)
        book_list = sel.css("#subject_list > ul > li")
        for book in book_list:
            item = BookItem()
            try:
                item["book_name"] = book.xpath("div[@class="info"]/h2/a/text()").extract()[0].strip()
                item["book_star"] = book.xpath("div[@class="info"]/div[2]/span[@class="rating_nums"]/text()").extract()[0].strip()
                item["book_pl"] = book.xpath("div[@class="info"]/div[2]/span[@class="pl"]/text()").extract()[0].strip()
                pub = book.xpath("div[@class="info"]/div[@class="pub"]/text()").extract()[0].strip().split("/")
                item["book_price"] = pub.pop()
                item["book_date"] = pub.pop()
                item["book_publish"] = pub.pop()
                item["book_author"] = "/".join(pub)
                yield item
            except:
                pass
        nextPage = sel.xpath("//div[@id="subject_list"]/div[@class="paginator"]/span[@class="next"]/a/@href").extract()[0].strip()
        if nextPage:
            next_url = "https://book.douban.com"+nextPage
            yield scrapy.http.Request(next_url,callback=self.parse)

其中scrapy.http.Request会回调parse函数,用try...catch是因为豆瓣图书并不是格式一致的。遇到有问题的数据,就抛弃不用。

突破反爬虫

一般来说,如果爬虫速度过快。会导致网站拒绝我们的访问,所以我们需要在settings设置爬虫的间隔时间,并关掉COOKIES

DOWNLOAD_DELAY = 2
COOKIES_ENABLED = False

或者,我们可以设置不同的浏览器UA或者IP地址来回避网站的屏蔽
下面用更改UA来作为例子。
在middlewares.py,编写一个随机替换UA的中间件,每个request都会经过middleware。
其中process_request,返回None,Scrapy将继续到其他的middleware进行处理。

class RandomUserAgent(object):
    def __init__(self,agents):
        self.agents = agents
    @classmethod
    def from_crawler(cls,crawler):
        return cls(crawler.settings.getlist("USER_AGENTS"))
    def process_request(self,request,spider):
        request.headers.setdefault("User-Agent",random.choice(self.agents))

接着道settings中设置

DOWNLOADER_MIDDLEWARES = {
"douban.middlewares.RandomUserAgent": 1,
}
...
USER_AGENTS = [
    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
    "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
    ...
]

再次运行程序,显然速度快了不少。

保存到MongoDB

接下来我们要将数据保存到数据库做持久化处理(这里用MongoDB举例,保存到其他数据库同理)。
这部分处理是写在pipelines中。在此之前我们还要先安装连接数据库的驱动。

pip install pymongo

我们在settings写下配置

# MONGODB configure
MONGODB_SERVER = "localhost"
MONGODB_PORT = 27017
MONGODB_DB = "douban"
MONGODB_COLLECTION = "book"
class MongoDBPipeline(object):
    def __init__(self):
        connection = MongoClient(
            host=settings["MONGODB_SERVER"],
            port=settings["MONGODB_PORT"]
        )
        db = connection[settings["MONGODB_DB"]]
        self.collection = db[settings["MONGODB_COLLECTION"]]

    def process_item(self, item, spider):
        self.collection.insert(dict(item))
        log.msg("Book  added to MongoDB database!",
                level=log.DEBUG, spider=spider)
        return item
其他

将运行项目的时候控制台中输出的DEBUG信息保存到log文件中。只需要在settings中设置

LOG_FILE = "logs/book.log"

项目代码地址:豆瓣图书爬虫

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/38421.html

相关文章

  • 爬虫学习之基于 Scrapy 的爬虫自动登录

    摘要:概述在前面两篇爬虫学习之基于的网络爬虫和爬虫学习之简单的网络爬虫文章中我们通过两个实际的案例,采用不同的方式进行了内容提取。 概述 在前面两篇(爬虫学习之基于Scrapy的网络爬虫和爬虫学习之简单的网络爬虫)文章中我们通过两个实际的案例,采用不同的方式进行了内容提取。我们对网络爬虫有了一个比较初级的认识,只要发起请求获取响应的网页内容,然后对内容进行格式化存储。很多时候我们抓取到的内容...

    Panda 评论0 收藏0
  • 23个Python爬虫开源项目代码,包含微信、淘宝、豆瓣、知乎、微博等

    摘要:今天为大家整理了个爬虫项目。地址新浪微博爬虫主要爬取新浪微博用户的个人信息微博信息粉丝和关注。代码获取新浪微博进行登录,可通过多账号登录来防止新浪的反扒。涵盖链家爬虫一文的全部代码,包括链家模拟登录代码。支持微博知乎豆瓣。 showImg(https://segmentfault.com/img/remote/1460000018452185?w=1000&h=667); 今天为大家整...

    jlanglang 评论0 收藏0
  • 零基础如何学爬虫技术

    摘要:楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,。本文来源知乎作者路人甲链接楚江数据提供网站数据采集和爬虫软件定制开发服务,服务范围涵盖社交网络电子商务分类信息学术研究等。 楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,http://www.chujiangdata.com。 第一:Python爬虫学习系列教程(来源于某博主:htt...

    KunMinX 评论0 收藏0
  • Scrapy学习(四) 爬取微博数据

    摘要:爬虫目标是获取用户的微博数关注数粉丝数。创建数据这部分我只需要个人信息,微博数,关注数分数数这些基本信息就行。 前言 Scrapy学习(三) 爬取豆瓣图书信息 接上篇之后。这次来爬取需要登录才能访问的微博。爬虫目标是获取用户的微博数、关注数、粉丝数。为建立用户关系图(尚未实现)做数据储备 准备 安装第三方库requests和pymongo 安装MongoDB 创建一个weibo爬虫项...

    LiveVideoStack 评论0 收藏0
  • scrapy入门教程——爬取豆瓣电影Top250!

    摘要:注意爬豆爬一定要加入选项,因为只要解析到网站的有,就会自动进行过滤处理,把处理结果分配到相应的类别,但偏偏豆瓣里面的为空不需要分配,所以一定要关掉这个选项。 本课只针对python3环境下的Scrapy版本(即scrapy1.3+) 选取什么网站来爬取呢? 对于歪果人,上手练scrapy爬虫的网站一般是官方练手网站 http://quotes.toscrape.com 我们中国人,当然...

    senntyou 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<