python实现爬虫(一)--- Scrapy框架抓取豆瓣书籍信息

  Scrapy是一个用python实现都爬虫框架,简单易用,功能强大,只需要在框架的基础上自定义自己的分析规则即可,具体如何新建工程等待都在官方文档上面讲解得非常清楚,官方文档tutorial(http://doc.scrapy.org/en/latest/intro/tutorial.html)请保证下载较新版本的Scrapy(我的是0.24.2,scrapy -v)旧版本会出现一些问题。

  下面我使用Scrapy抓取豆瓣上面编程书籍的一些简单信息

一、准备爬取的页面如下,新建一个douban工程:

  每一页有20本书籍,虽然下面显示由97页,实际上只有50页,也即1000本书籍,非常快就可以抓取下来

(非常开心看到自己最喜欢的两本书排在前两位《算法导论》and《深入理解计算机系统》 ^_^)

二、确定所需信息为(title, link, author, price, description),编辑items.py文件,添加所需的项

  

三、定义自己的爬虫,在douban/douban/spiders/目录下新建一个.py文件(此处sola.py)

1. 导入所需模块,此处的爬虫继承自最简单的Spider, 除此之外scrapy还实现了CrawlSpider等功能更强大的爬虫可以使用

  

2.确定 爬虫名字是sola,必须唯一 ; allowed_domains: 允许在book.douban.com 域名下抓取; 以及起始url

3. 编写parse函数,parse函数是对每一url请求返回的响应所对应作出的分析

parse函数由两部分组成,第一部分是如何处理相应所获的的书籍信息(Item),第二部分是如何递归抓取下一页面的书籍, 也就是返回item和Request的问题

1)处理Item

首先查看网页源码,可以发现每一本书籍对应的html文档如下(以下以《编程珠玑》为例),

 1 <li class="subject-item">
 2     <div class="pic">
 3       <a class="nbg" href="http://book.douban.com/subject/3227098/"
 4   onclick="moreurl(this,{i:'5'})" }>
 5         <img class="" src="http://img3.douban.com/mpic/s4687321.jpg"
 6           width="90">
 7       </a>
 8     </div>
 9     <div class="info">
10       <h2 class="">
11
12
13   <a href="http://book.douban.com/subject/3227098/" title="编程珠玑"
14   onclick="moreurl(this,{i:'5'})">
15
16     编程珠玑
17
18   </a>
19
20       </h2>
21       <div class="pub">
22
23
24   Jon Bentley / 黄倩、钱丽艳 / 人民邮电出版社 / 2008-10 / 39.00元
25
26       </div>
27
28   <div class="star clearfix">
29         <span class="allstar45"></span>
30         <span class="rating_nums">9.2</span>
31
32     <span class="pl">
33         (1387人评价)
34     </span>
35   </div>
36
37     <p>本书是计算机科学方面的经典名著。书的内容围绕程序设计人员面对的一系列实际问题展开。作者Jon Bentley 以其独有的洞察力和创造力,引导读者理解这些问题... </p>
38
39       <div class="ft">
40
41   <div class="collect-info">
42   </div>
43
44     <div class="buy-info">
45
46         <a href="http://book.douban.com/subject/3227098/buylinks">
47             有售
48           27.60 元起
49         </a>
50     </div>
51
52
53       </div>
54
55     </div>
56   </li>

所以首先找到所有 <li class="subject-item">的元素 : info = Selector(response).xpath(‘//li[@class="subject-item"]‘)

然后对于每一个<li class="subject-item">元素,可以发现书籍信息在里面的<div class="info">元素里,title和link在div里面的<h2 class="">的a元素中,作者和价格在<div class="pub">的文本中(这里需要对字符串进行处理,取出‘/’ 划分的子串的第一个和最后一个),而描述则在<p>元素中(后面有一些书籍没有描述,所以这里需要增加一些特殊处理), 所以得到的对书籍的处理代码如下:

 1     def parse(self, response):
 2         books = []
 3         sel = Selector(response)
 4         info = sel.xpath(‘//li[@class="subject-item"]‘)
 5         if len(info) == 0:
 6             raise CloseSpider(‘---------------------End Search!---------------‘)
 7
 8
 9         f = open(‘books.data‘,‘a‘)
10         for site in info.xpath(‘div[@class="info"]‘):
11             book = DoubanItem()
12             book[‘title‘] = site.xpath(‘h2/a/@title‘).extract()[0].encode(‘utf-8‘)
13             book[‘link‘] = site.xpath(‘h2/a/@href‘).extract()[0].encode(‘utf-8‘)
14             pub = site.xpath(‘div[@class="pub"]/text()‘).extract()[0].encode(‘utf-8‘)
15             pub = pub.strip().split(‘/‘)
16
17             book[‘author‘] = pub[0]
18             book[‘price‘] = pub[-1]
19             desc = site.xpath(‘p/text()‘).extract()
20             book[‘desc‘] =  desc[0].encode(‘utf-8‘) if (len(desc) != 0) else ‘‘
21             print(‘-----------------lALALALALALA----------------------------------------------‘)
22             print(book[‘title‘])
23             print(book[‘link‘])
24             print(book[‘author‘])
25             print(book[‘price‘])
26             print(book[‘desc‘])
27             ss = "{‘title‘: ‘" + book[‘title‘] + "‘ , " + "‘link‘: ‘" + book[‘link‘] + "‘ , " + "‘author‘: ‘" + book[‘author‘] + "‘ , " + "‘price‘: ‘" + book[‘price‘] + "‘ , " + "‘desc‘: ‘" + book[‘desc‘] + "‘}"
28            29             target = json.dumps(ss, ensure_ascii=False)   // 转换成json格式保存到文件中
30            31             f.write(target+‘\n‘)
32             print(‘-----------------lALALALALALA----------------------------------------------\n\n‘)
33             books.append(book)
34             yield book

2)返回Request,继续抓取下一页面

查看源码只需每次返回下一页的链接(注意url是采用utf-8编码,关于编码的知识这两篇博客写得很好,给博主赞一个:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html),也就是找到<span class="next">元素,抽取其中的href链接,然后并上“http://book.douban.com”即可得到下一页的连接,最后使用 yield scrapy.Request(new_url, callback=self.parse) 会默认递归继续执行下去。

 1         <div class="paginator">
 2         <span class="prev">
 3             &lt;前页
 4         </span>
 5
 6
 7
 8                 <span class="thispage">1</span>
 9
10             <a href="/tag/编程?start=20&amp;type=T" >2</a>
11
12
13             <a href="/tag/编程?start=40&amp;type=T" >3</a>
14
15
16             <a href="/tag/编程?start=60&amp;type=T" >4</a>
17
18
19             <a href="/tag/编程?start=80&amp;type=T" >5</a>
20
21
22             <a href="/tag/编程?start=100&amp;type=T" >6</a>
23
24
25             <a href="/tag/编程?start=120&amp;type=T" >7</a>
26
27
28             <a href="/tag/编程?start=140&amp;type=T" >8</a>
29
30
31             <a href="/tag/编程?start=160&amp;type=T" >9</a>
32
33             <span class="break">...</span>
34
35             <a href="/tag/编程?start=1900&amp;type=T" >96</a>
36
37             <a href="/tag/编程?start=1920&amp;type=T" >97</a>
38
39         <span class="next">
40             <link rel="next" href="/tag/编程?start=20&amp;type=T"/>
41             <a href="/tag/编程?start=20&amp;type=T" >后页&gt;</a>
42         </span>
43
44         </div>

四、这样子只要在主目录下面运行 scrapy crawl sola就可以得到所有1000本书籍的信息(终端及books.data)

  当爬取到没有书籍的时候应及时关掉爬虫~~

  结果如下:

  这里本可以使用 -o items.json 自动生成一个json文件,但是得到的文件始终无法显示中文,经过一整天的查找与尝试猜测scrapy框架里面可能是使用dumps()函数时没有给第二个参数ensure_ascii 赋值为False, 导致只能以Ascll码解析为json文件。希望知道如何输出为中文的朋友指点一下~

sola.py 代码:

import scrapy
import json
from scrapy.selector import Selector
from scrapy.spider import Spider
from douban.items import DoubanItem
from scrapy.exceptions import CloseSpider

class DoubanSpider(Spider):
    name = ‘sola‘
    allowed_domains = [‘book.douban.com‘]
    start_urls = [
            ‘http://book.douban.com/tag/%E7%BC%96%E7%A8%8B‘
            ]

    def parse(self, response):
        books = []
        sel = Selector(response)
        info = sel.xpath(‘//li[@class="subject-item"]‘)
        if len(info) == 0:
            raise CloseSpider(‘---------------------End Search!---------------‘)

        f = open(‘books.data‘,‘a‘)
        for site in info.xpath(‘div[@class="info"]‘):
            book = DoubanItem()
            book[‘title‘] = site.xpath(‘h2/a/@title‘).extract()[0].encode(‘utf-8‘)
            book[‘link‘] = site.xpath(‘h2/a/@href‘).extract()[0].encode(‘utf-8‘)
            pub = site.xpath(‘div[@class="pub"]/text()‘).extract()[0].encode(‘utf-8‘)
            pub = pub.strip().split(‘/‘)

            book[‘author‘] = pub[0]
            book[‘price‘] = pub[-1]
            desc = site.xpath(‘p/text()‘).extract()
            book[‘desc‘] =  desc[0].encode(‘utf-8‘) if (len(desc) != 0) else ‘‘
            print(‘-----------------lALALALALALA----------------------------------------------‘)
            print(book[‘title‘])
            print(book[‘link‘])
            print(book[‘author‘])
            print(book[‘price‘])
            print(book[‘desc‘])
            ss = "{‘title‘: ‘" + book[‘title‘] + "‘ , " + "‘link‘: ‘" + book[‘link‘] + "‘ , " + "‘author‘: ‘" + book[‘author‘] + "‘ , " + "‘price‘: ‘" + book[‘price‘] + "‘ , " + "‘desc‘: ‘" + book[‘desc‘] + "‘}"
            print ss
            target = json.dumps(ss, ensure_ascii=False)
            print target
            f.write(target+‘\n‘)
            print(‘-----------------lALALALALALA----------------------------------------------\n\n‘)
            books.append(book)
            yield book

        f.close()

        site = sel.xpath(‘//span[@class="next"]/a/@href‘).extract()[0]
        print(‘url: ‘ + response.url)
        print(‘site: ‘ + site)
        temp = response.url.split(‘/‘)
        new_url = temp[0]
        i = 1
        while i < len(temp)-2:
           new_url += ‘/‘ + temp[i]
           i += 1
        new_url += site
        new_url = new_url.encode(‘utf-8‘)
        print(‘url: ‘ + new_url)
        yield scrapy.Request(new_url, callback=self.parse)

  

python实现爬虫(一)--- Scrapy框架抓取豆瓣书籍信息

时间: 2024-10-16 01:34:17

python实现爬虫(一)--- Scrapy框架抓取豆瓣书籍信息的相关文章

Python网络爬虫之Scrapy框架(CrawlSpider)

目录 Python网络爬虫之Scrapy框架(CrawlSpider) CrawlSpider使用 爬取糗事百科糗图板块的所有页码数据 Python网络爬虫之Scrapy框架(CrawlSpider) 提问:如果想要通过爬虫程序去爬取"糗百"全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基于CrawlSpider的自动爬取进行实现(更加简洁和高效). CrawlSpider使

爬虫学习 16.Python网络爬虫之Scrapy框架(CrawlSpider)

爬虫学习 16.Python网络爬虫之Scrapy框架(CrawlSpider) 引入 提问:如果想要通过爬虫程序去爬取"糗百"全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基于CrawlSpider的自动爬取进行实现(更加简洁和高效). 今日概要 CrawlSpider简介 CrawlSpider使用 基于CrawlSpider爬虫文件的创建 链接提取器 规则解析器 今日详

03_使用scrapy框架爬取豆瓣电影TOP250

前言: 本次项目是使用scrapy框架,爬取豆瓣电影TOP250的相关信息.其中涉及到代理IP,随机UA代理,最后将得到的数据保存到mongoDB中.本次爬取的内容实则不难.主要是熟悉scrapy相关命令以及理解框架各部分的作用. 1.本次目标 爬取豆瓣电影TOP250的信息,将得到的数据保存到mongoDB中. 2.准备工作 需要安装好scrapy以及mongoDB,安装步骤这里不做赘述.(这里最好是先了解scrapy框架各个部分的基本作用和基础知识,这样方便后面的内容的理解.scrapy文档

使用python scrapy框架抓取cnblog 的文章内容

scrapy 的文档请移驾到 http://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/install.html 1.准备工作  安装python .Spyder .scrapy 如果想要数据直接入mysql 还需要安装python的 MySQLdb 依赖包 本人mac操作系统 安装MySQLdb的时候出现了些小问题  最后是重装了openssl 才通过的 Spyder 是编写python的ide 2.新建项目  cd /usr/local/var/ww

基于python的scrapy框架爬取豆瓣电影及其可视化

1.Scrapy框架介绍 主要介绍,spiders,engine,scheduler,downloader,Item pipeline scrapy常见命令如下: 对应在scrapy文件中有,自己增加爬虫文件,系统生成items,pipelines,setting的配置文件就这些. items写需要爬取的属性名,pipelines写一些数据流操作,写入文件,还是导入数据库中.主要爬虫文件写domain,属性名的xpath,在每页添加属性对应的信息等. movieRank = scrapy.Fie

Python开发爬虫之动态网页抓取篇:爬取博客评论数据

以爬取<Python 网络爬虫:从入门到实践>一书作者的个人博客评论为例.网址:http://www.santostang.com/2017/03/02/hello-world/ 1)"抓包":找到真实的数据地址 右键点击"检查",点击"network",选择"js".刷新一下页面,选中页面刷新时返回的数据list?callback....这个js文件.右边再选中Header.如图: 其中,Request URL即

18、python网路爬虫之Scrapy框架中的CrawlSpider详解

CrawlSpider的引入: 提问:如果想要通过爬虫程序去爬取"糗百"全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基于CrawlSpider的自动爬取进行实现(更加简洁和高效) CrawlSpider的简介: CrawlSpider其实是Spider的一个子类,除了继承到Spider的特性和功能外,还派生除了其自己独有的更加强大的特性和功能.其中最显著的功能就是"

Python 爬虫学习3 -简单抓取小说网信息

小说网 https://www.qu.la/paihangbang/ 功能:抓取每个排行榜内的小说名和对应链接,然后写入excel表格里面. 按F12 审查页面元素可以得到你所要的信息的class,从而来定位. 具体看代码讲解吧. #coding:utf-8 #为了正常转码 必写 import codecs #为下面新建excel,转码正确准备得一个包 __author__ = 'Administrator' import requests from bs4 import BeautifulSo

scrapy框架爬取豆瓣读书(1)

1.scrapy框架 Scrapy,Python开发的一个快速.高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试. Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改.它也提供了多种类型爬虫的基类,如BaseSpider.sitemap爬虫等,最新版本又提供了web2.0爬虫的支持. 主要组件: 2.快速开始 scrapy startproject douban cd到douban根目录