使用scrapy抓取糗事百科

1、安装scrapy

pip install scrapy

2、新建一个项目

root@ubuntu:~# scrapy --help
Scrapy 1.0.5 - no active project

Usage:
  scrapy <command> [options] [args]

Available commands:
  bench         Run quick benchmark test
  commands      
  fetch         Fetch a URL using the Scrapy downloader
  runspider     Run a self-contained spider (without creating a project)
  settings      Get settings values
  shell         Interactive scraping console
  startproject  Create new project
  version       Print Scrapy version
  view          Open URL in browser, as seen by Scrapy

  [ more ]      More commands available when run from project directory

Use "scrapy <command> -h" to see more info about a command

查了下命令,使用startproject

scrapy startproject  qiubai

可以看到这里生成了名为qiubai的文件

3、打开浏览器进入糗事百科网站,我们看到有每页有很多条糗事

我们主要获取:作者名,作者头像、文字内容、附加图片、好笑(赞次数)、评论次数

4、修改items.py文件, 新建一个itme类

import scrapy

class QiubaiItem(scrapy.Item):
    # define the fields for your item here like:

    author      = scrapy.Field()    # 作者
    author_logo = scrapy.Field()    # 作者头像

    content     = scrapy.Field()    # 内容
    thumb       = scrapy.Field()    # 内容图片

    vote        = scrapy.Field()    # 赞人数
    comments    = scrapy.Field()    # 评论数

5、添加一个spiders文件,这里我新建文件qiubai_spi.py
右键审查元素

每条糗事为以div包裹,我们点开其中的div

由此我们新建QiubaiSpider类用于抓取数据

import scrapy
from scrapy.http import Request
from qiubai.items import QiubaiItem


class QiubaiSpider(scrapy.Spider):

    name = "qiubai"

    start_urls = (
        'http://www.qiushibaike.com',
    )


    def parse(self, response):

        item = QiubaiItem() 

        for mb in response.xpath('//div[@class="article block untagged mb15"]'):
            author = mb.xpath('div[@class="author clearfix"]/a/h2/text()').extract()[0]

            author_logo = mb.xpath('div[@class="author clearfix"]/a/img/@src').extract()[0]

            content = mb.xpath('div[@class="content"]/text()').extract()[0]

            # 纯文字的糗事,没有图片
            thumb = ""
            try:
                thumb = mb.xpath('div[@class="thumb"]/a/img/@src').extract()[0]
            except Exception, e:
                pass


            item['author'] = author.encode('utf-8')     # 转码
            item['author_logo'] = author_logo
            item['content'] = content.encode('utf-8')
            item['thumb'] = thumb
            item['vote'] = vote
            item['comments'] = comments.encode('utf-8')

            yield item

这里需要在settings.py加上这个

`ITEM_PIPELINES = {
   'qiubai.pipelines.QiubaiPipeline': 300,
}

6、运行爬虫

scrapy crawl qiubai

发现报错了,好像不能直接范围怎么办呢?
你应该想到了,伪造头部,要他觉得我们是浏览器

7、最后代码
加上头部后就可以正常抓取,抓取的时候你可能发现有些会发生错误,那是因为糗事百科前端布局比较变态,比如是匿名发送时,div结果不一样,你需要单独解析。所以下边你会看到很多异常处理,大家可以自己试下。
我这边最后还增加了抓取每一页的一个循环调用,至于解析页码也请大家自己实现

import scrapy
from scrapy.http import Request
from qiubai.items import QiubaiItem


class QiubaiSpider(scrapy.Spider):

    name = "qiubai"

    start_urls = (
        # 'http://www.qiushibaike.com/pic/',
        'http://www.qiushibaike.com',
    )

    # 伪造的头部
    headers = {
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "Accept-Encoding": "gzip, deflate, sdch",
        "Accept-Language": "zh-CN,zh;q=0.8",
        "Cache-Control": "max-age=0",
        "Cookie": "CAMPUS_CHECKED=0; JYERN=0.6521779221948236; CAMPUS_CHECKED=0; QS_ED=6; JYERN=0.26531747193075716; QS_GD=7; QS_TM=1; jyean=ZnkIgT1JW7dtwnfPBYUOaQMQ9EHw9Hrhs72JCf4tOTiBEDLIHPZF72BzqUmmVHNWAvt1xk4aizTajtIpfTvTrEE39lecGsS2bVqdUtacbOjnYA2_qVZSih0wl0Ao7Xe00; LF_Email=njxczx08@xyh.com; jy=34C4C600E19323AE7A3588D4651301956A3437AFB5608381E05974D4BC275FA19D4906C1AEFC7D6B868F1A2D306BA4CB38C39F61AB200E02C4A6E6C5F2E1F98D0DBDA7E364FF1E25FB83D488DADBAD62E34C4D6FCA3E4AC9D210FD33668A9E3668258E09AFEF7516B65E7FFEB527606F357ED5F7D5BA8F058BE2EAAE46A7E9403003873D2D71D7DFB3F3C856AD2FFF3AE152FC747C3A7365F0F303CA534515EC779046E472AC790853495CA08517EC6095A325835A7019E2906974067015501F864B8B9CBD1F6AF16CDC4B8BD248876DD343B4367C517BAB05B6701AD2E488A1C3E320B7AD676CFC15E219850E12EBAB82B63CC4ED9A740E8511C4EF3449BE09; jye_notice_show=1|2015/8/31 15:08:32|0|false; JYERN=0.39406700897961855; CAMPUS_CHECKED=0; jye_math_ques_s=0; jye_math_ques_d=0; jye_math_ques_t=1; jye_math_ques_0_q=070eac9c-ad95-44f1-909c-869dbb4c874a~803641a7-c36b-483b-9f8d-ac0a5522e3c3~; CNZZDATA2018550=cnzz_eid%3D484121901-1440586726-http%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1441002725; _cnzz_CV2018550=%E7%94%A8%E6%88%B7%E4%BB%98%E8%B4%B9%7C%E9%9D%9EVIP%E7%94%A8%E6%88%B7%7C1441006330746%26%E7%94%A8%E6%88%B7%E8%A7%92%E8%89%B2%7C%E8%80%81%E5%B8%88%7C14",
        "Host": "www.qiushibaike.com",
        "Proxy-Connection": "keep-alive",
        "Referer": "http://www.qiushibaike.com/",
        "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/40.0.2214.111 Chrome/40.0.2214.111 Safari/537.36"
    }

    def start_requests(self):
        for url in self.start_urls:
            yield self.make_requests_from_url(url)

    def make_requests_from_url(self, url):

        return Request(url, headers=self.headers, dont_filter=True)

    def parse(self, response):

        item = QiubaiItem()

        for mb in response.xpath('//div[@class="article block untagged mb15"]'):
            try:
                # 部分为匿名发布,所有以常规解析会出错
                try:
                    # 正常发布
                    author = mb.xpath('div[@class="author clearfix"]/a/h2/text()').extract()[0]
                except Exception, e:
                    # 匿名发布
                    author = mb.xpath('div[@class="author clearfix"]/span/h2/text()').extract()[0]

                # 部分为匿名发布,所有以常规解析会出错
                try:
                    # 正常发布
                    author_logo = mb.xpath('div[@class="author clearfix"]/a/img/@src').extract()[0]
                except Exception, e:
                    author_logo = mb.xpath('div[@class="author clearfix"]/span/img/@src').extract()[0]

                content = mb.xpath('div[@class="content"]/text()').extract()[0]

                # 纯文字的糗事,没有图片
                thumb = ""
                try:
                    thumb = mb.xpath('div[@class="thumb"]/a/img/@src').extract()[0]
                except Exception, e:
                    pass

                vote = ""
                try:
                    vote = mb.xpath('div[@class="stats"]/span[@class="stats-vote"]/i/text()').extract()[0]
                except Exception, e:
                    # 赞为空
                    pass

                comments = ""
                try:
                    # 评论为空
                    comments = mb.xpath('div[@class="stats"]/span[@class="stats-comments"]/a/i/text()').extract()[0]
                except Exception, e:
                    pass

                item['author'] = author.encode('utf-8')     # 转码
                item['author_logo'] = author_logo
                item['content'] = content.encode('utf-8')
                item['thumb'] = thumb
                item['vote'] = vote
                item['comments'] = comments.encode('utf-8')

                # print "===================================="*3
                # print "author       :", item['author']
                # print "author_logo  :", item['author_logo']
                # print "content      :", item['content']
                # print "thumb        :", item['thumb']
                # print "vote         :", item['vote']
                # print "comment      :", item['comments']
                # print "\r\n"
                yield item
            except Exception, e:
                print "get info error! continue get next info!"
                continue

        # 获取下一页的链接
        pages = response.xpath('//ul[@class="pagination"]/li')
        next_page = pages[-1].xpath('a/@href').extract()[0]

        # 如果已经时最后一页了,在继续就到更多内容了,这里我们只抓取首页的内容
        if next_page == '/hot':
            print "====over===="
            return
        else:
            next_page_url = self.start_urls[0] + next_page
            yield Request(url=next_page_url, headers=self.headers, callback=self.parse)

git源码地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容