spiders——简书7日热门(scrapy)

经过不断的修改和尝试终于成功的获取到了简书七日热门的数据,主要爬取了以下几个字段:
1.用户
2.标题
3.阅读量
4.评论量
5.获赞量
6.打赏数
7.文章发表时间
8.被哪些专题收录
<strong> 首先我们可以先看一下我们要获取字段的位置 </strong>

Paste_Image.png

<em>框中的其他数据都可以通过xpath获取到,标注箭头的为我在当前页面通过xpath获取不到的或者出现问题的,不过别着急,二级页面中包含我们想要的所有数据。</em>

Paste_Image.png

<em> 从这个页面我们可以看到,在第一级页面中的数据,在这一页都可以看到,但我们只选取我们想要的字段,箭头指向的为上一级页面中通过xpath获取出现问题的字段,在当前页面获取同样出现了问题,所以果断采用正则在源码中获取</em>

Paste_Image.png

<em>我们可以看到在源码中可以看到这些字段,那么就可以通过正则来匹配相应的字段</em>
<strong>我们可以看一下这一篇文章被哪些专题收录,在文章的最下边</strong>

Paste_Image.png

现在我们整明白了所有字段的位置,接下来就开始去抓取这些字段,首先我们先分析页面的分页问题,通过观察发现页面是动态加载的,再点击更多后会请求新的数据,我们来看一下整个页面的url规则,以及获取被收录专题的数据的url规则,我这里简单列一下一些截图,具体可以参考罗罗攀Python爬虫之简书七日热门数据爬取(异步加载详解),写的特别详细。

Paste_Image.png
Paste_Image.png

<em>通过这些字段我们可以想到一种构造url的方法</em>

def start_requests(self):
        for a in range(1,6):
            self.url = 'http://www.jianshu.com/trending/weekly?&page=%s' %a
            yield scrapy.Request(self.url,self.parse)

我们再来看一下被收录专题的url规则

<em>从这两张图可以看出,URL主要变化点在id和和page,<strong>ID</strong>可以从第三张图片中通过正则从源码获取从最后一张图可以看出收录的专题数有<strong>5页</strong>专题名都存在<strong>title</strong>中所以我们就可以通过第一条URL获取总页数,然后构造其他的url。
构造方法如下:</em>

        id = re.findall('{"id":(.*?),', response.text, re.S)[0]
        url = 'http://www.jianshu.com/notes/%s/included_collections?page=1' %id
        datas = []
        result = requests.get(url)
        data = json.loads(result.text)
        for one in data['collections']:
            datas.append(one['title'])
        count = data['total_pages']
        for one in range(2,count+1):
            url = 'http://www.jianshu.com/notes/{}/included_collections?page={}'.format(id,one)
            result = requests.get(url)
            data = json.loads(result.text)
            for one in data['collections']:
                datas.append(one['title'])

<strong>通过以上方法可以成功的找到页面和数据,接下来一个很重要的问题,怎们在多级页面中统一数据,因为我们所有的数据是集中在两个页面是实现的,那么怎样才可以实现多级页面传递数据呢?</strong>
完成多级页面传递参数主要是通过<strong>meta</strong>这个属性,具体传递方法可以参照向右奔跑老大的Scrapy抓取在不同级别Request之间传递参数,这篇文章有很详细的介绍。
在这个地方遇到的一个坑:多级页面传递后,发现总是存的是重复的内容,在这里一定要注意,因为肯定是使用for循环去获取相关标题的URL然后进入子页面去获取其他相关字段的信息,但是如果在这个地方定义了item,然后在多级传递参数,就可能出现重复的情况,所以就采用了在第一级页面获取到的数据先用变量存储,通过meta这个属性标签带入二级页面,可以看一下处理代码:

        for one in result:
            user = one.xpath('div[1]/div/a/text()').extract()[0]
            title = one.xpath('a/text()').extract()[0]
            zan = one.xpath('div[2]/span[1]/text()').extract()[0]
            try:
                shang = one.xpath('div[2]/span[2]/text()').extract()[0]
            except:
                shang = u'0'
            publish = one.xpath('div[1]/div/span/@data-shared-at').extract()[0]
            link = one.xpath('a/@href').extract()[0]
            url = urljoin_rfc(base_url,link)
            yield scrapy.Request(url,meta={'user':user,'title':title,
                                                'zan':zan,'shang':shang,'publish':publish},callback=self.parse_type)

<strong>通过上边的简单介绍,应该对整个流程和规则有了一定的了解,下边直接上代码</strong>

1.item.py

import scrapy
class JianshuItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    user = scrapy.Field() #用户
    title = scrapy.Field() #标题
    count_read = scrapy.Field() #阅读量
    ping = scrapy.Field() #评论量
    count_zan = scrapy.Field() #喜欢
    shang = scrapy.Field()  #赞赏
    publish = scrapy.Field() #时间
    sp_title = scrapy.Field() #被专题书录

2.jianshuSpider.py

#-*- coding:utf-8 -*-
import scrapy
from ..items import JianshuItem
from scrapy.utils.url import urljoin_rfc
import requests
import re
import json
class jianshuSpider(scrapy.Spider):
    name = 'jianshu'
    def start_requests(self):
        for a in range(1,6):
            self.url = 'http://www.jianshu.com/trending/weekly?&page=%s' %a
            yield scrapy.Request(self.url,self.parse)
    def parse(self, response):
        result = response.xpath('/html/body/div[1]/div/div[1]/div/ul/li/div')
        base_url = 'http://www.jianshu.com'
        for one in result:
            user = one.xpath('div[1]/div/a/text()').extract()[0]
            title = one.xpath('a/text()').extract()[0]
            zan = one.xpath('div[2]/span[1]/text()').extract()[0]
            try:
                shang = one.xpath('div[2]/span[2]/text()').extract()[0]
            except:
                shang = u'0'
            publish = one.xpath('div[1]/div/span/@data-shared-at').extract()[0]
            link = one.xpath('a/@href').extract()[0]
            url = urljoin_rfc(base_url,link)
            yield scrapy.Request(url,meta={'user':user,'title':title,
                                                'zan':zan,'shang':shang,'publish':publish},callback=self.parse_type)
    def parse_type(self,response):
        item = JianshuItem()
        item['user'] = response.meta['user']
        item['title'] = response.meta['title']
        item['count_read'] = re.findall('"views_count":(.*?),',response.text,re.S)[0]
        item['ping'] = re.findall('"comments_count":(.*?),',response.text,re.S)[0]
        item['count_zan'] = response.meta['zan']
        item['shang'] = response.meta['shang']
        item['publish'] = response.meta['publish']
        id = re.findall('{"id":(.*?),', response.text, re.S)[0]
        url = 'http://www.jianshu.com/notes/%s/included_collections?page=1' %id
        datas = []
        result = requests.get(url)
        data = json.loads(result.text)
        for one in data['collections']:
            datas.append(one['title'])
        count = data['total_pages']
        for one in range(2,count+1):
            url = 'http://www.jianshu.com/notes/{}/included_collections?page={}'.format(id,one)
            result = requests.get(url)
            data = json.loads(result.text)
            for one in data['collections']:
                datas.append(one['title'])
        try:
            item['sp_title'] = " ".join(datas).encode('utf-8')
        except:
            item['sp_title'] = u''
        yield item

3.结果

总结

先说一下存在的问题:
在对一个页面进行爬取的时候没做一个整体的考虑,所以在不同页面之前传递的参数比较多,代码看起来有点乱,之后可以将所有的数据全部在二级页面获取。
还有一点,可以看到在处理json数据那一块,我选择使用了requests库去操作,这是因为如果使用scrapy.Request去操作的话,要通过回调函数去处理,还要在进行参数的传递,造成很多麻烦,然后准备尝试去写一个用requests和beautifulsoup爬虫,进行一个对比。
<strong>写的第一篇关于思想和技术方面的文章,由于时间的关系所以可能解释的不是很详细,如果存在问题可以在下方评论一起探讨。
最后还是要感谢一下罗罗攀向右奔跑的相关文章和罗罗攀大哥无私的帮助,如果有时间的话会对数据进一步处理,做一个相关分析。</strong>

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

推荐阅读更多精彩内容

  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,652评论 0 15
  • 语文学科一门独特的综合性课程,“质胜文则野,文胜质则史”,入选在教材中的文本均是古今中外的精粹之作。“一切语言的尽...
    噜噜890108阅读 266评论 0 2
  • 钢笔画是用钢笔(其他类似钢笔笔触的圆珠笔、中性笔、针管笔)画的画。钢笔画线条果断,黑白分明,干脆响亮,具有...
    总有一朵花是香的阅读 3,583评论 20 35
  • ▓▓▓▓▓▓░░░░░░░░░ 44%——By @YearPogress 行业学习 暂停+2。没理由,没学习。 学...
    Luffy_Zhu阅读 107评论 0 0