今日头条爬虫解析

如今自媒体风生水起,很多人开始入住各大自媒体平台进行自媒体创作。想要持续的输出高质量的文章太难了,于是很多人就开始搞起了伪原创,拿别人比较热的文章过来改一改,不仅轻松还能收获一票粉丝,偏题了,我不是鼓励大家搞伪原创。今天我们的主题是爬虫,既然自媒体平台有这么多高质量的文章,想要一一收藏太难了,于是就想出了通过网络爬虫将感兴趣的文章爬取下来然后进行收藏,岂不是很爽,于是开始动手。今天拿今日头条练手。

第一步分析入口,今日头条的文章入口主要分为频道入口,搜索入口,用户主页入口,那么我们就一一开始破解。

首先从频道入口下手,分析网页结构,发现所有的文章都是通过ajax动态加载,那么第一想法是通过selenium模拟浏览器进行网页提取,虽然目的可以达到但是效果不理想,需要处理分页去重而且效率不高,故这个方案放弃,在接着进行分析ajax接口,貌似行得通,架起代码开始测试,在处理ajax接口是发现需要处理as,cp,_signature 三个参数,接口如下

https://www.toutiao.com/api/pc/feed/?category=news_tech&utm_source=toutiao&widen=1&max_behot_time=0&max_behot_time_tmp=0&tadrequire=true&as=A125AB7BC7F0F59&cp=5BB7802FF5896E1&_signature=NOFpxAAAb1yLl5gie2NwDTThad

as,cp网上已经有大神破解了算法如下;

    def getASCP(self):
        t = int(math.floor(time.time()))
        e = hex(t).upper()[2:]
        m = hashlib.md5()
        m.update(str(t).encode(encoding='utf-8'))
        i = m.hexdigest().upper()

        if len(e) != 8:
            AS = '479BB4B7254C150'
            CP = '7E0AC8874BB0985'
            return AS, CP

        n = i[0:5]
        a = i[-5:]
        s = ''
        r = ''
        for o in range(5):
            s += n[o] + e[o]
            r += e[o + 3] + a[o]

        AS = 'A1' + s + e[-3:]
        CP = e[0:3] + r + 'E1'
        return AS, CP

比较难搞的是signature参数,虽然网上也有很多人发文怎么破解,但是效果都不理想,只能拿到第一次请求的signature,第二次请求就直接不行了。分析js发现signature的请求是通过window.TAC.sign方法产生,而这个方法是动态绑定的,由一堆看不清逻辑的字符串通过一定的算法解密后得到,着手分析了一下,发现里面用到了Date ,Convas 相关的函数,姑且进行了一下推断,判断入参的时间戳跟当前的时间戳进行对比,肯定不能大于当前的时间,但是范围也不能相差太远否则一个频道页内容直接就爆了,对于Convas 可能就是为了限定上下文,否则为什么我们通过python直接执行TAC.sign方法产生的signature在第二次就会失效,虽说第一次能请求成功那么我们是不是每次都模拟第一次请求,虽说也能得到数据,但不能连续采集还是有点失望的。那有没有其他的办法可以解决了,在经过一下午的思考过后发现,既然在保证上下文的情况下可以连续采集(通过chrome的console生成的signature是可以的)那么我们通过selenium方案来模拟上下文,负责产生signature,剩下的就是通过urllib来请求接口获取数据进行解析是否可以行了?经过一番验证结果是可喜的,功夫不负有心人达到目的。直接贴代码。代码中有些自有逻辑没有贴出来,但是逻辑思路基本上都有了。今天到此为止,下次说怎么爬详情


    def get_channel_data(self, page):  #获取数据
        req = self.s.get(url=self.url, verify=False, proxies=get_proxy_ip())
        #print (self.s.headers)
        #print(req.text)
        headers = {'referer': self.url}
        max_behot_time='0'
        signature='.1.hXgAApDNVcKHe5jmqy.9f4U'
        eas = 'A1E56B6786B47FE'
        ecp = '5B7674A7FF2E9E1'
        self.s.headers.update(headers)
        item_list = []
        browser = webdriver.Chrome()
        browser.implicitly_wait(10)
        browser.get(self.url)
        for i in range(0, page):

            Honey = json.loads(self.get_js())
            # eas = self.getHoney(int(max_behot_time))[0]
            # ecp = self.getHoney(int(max_behot_time))[1]
            eas = Honey['as']
            ecp = Honey['cp']
            signature = Honey['_signature']
            if i > 0:
                signature = browser.execute_script("return window.TAC.sign("+ max_behot_time +")")
            url='https://www.toutiao.com/api/pc/feed/?category={}&utm_source=toutiao&widen=1&max_behot_time={}&max_behot_time_tmp={}&tadrequire=true&as={}&cp={}&_signature={}'.format(self.channel,max_behot_time,max_behot_time,eas,ecp,signature)
            req=self.s.get(url=url, verify=False, proxies=get_proxy_ip())
            time.sleep(random.random() * 2+2)
            # print(req.text)
            # print(url)
            j=json.loads(req.text)
            for k in range(0, 10):
                item = toutiaoitem()
                now=time.time()
                if j['data'][k]['tag'] != 'ad' or j['data'][k]['tag'] != 'ad.platform.site':
                    item.title = j['data'][k]['title']  ##标题
                    item.source = j['data'][k]['source']  ##作者
                    item.source_url = 'https://www.toutiao.com/'+j['data'][k]['source_url']   ##文章链接
                    item.media_url = 'https://www.toutiao.com/'+j['data'][k]['media_url']  #作者主页
                    item.article_genre = j['data'][k]['article_genre']  #文章类型
                    try:
                        item.comments_count = j['data'][k]['comments_count']  ###评论
                    except:
                        item.comments_count = 0

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,392评论 25 707
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,680评论 2 59
  • 最近一直在学习python的scrapy框架。写了比较多的小例子。工欲善其事必先利其器。今天描述的就是爬取今日头条...
    Evtion阅读 7,327评论 6 6
  • 你走了一个寒冬来这里赏花, 花期已过。 你,不必叹息。 你背着行囊去远方追逐梦想, 似梦非梦。 你,不...
    稚兮阅读 360评论 0 0
  • 孙小猛~河北惠友集团 【日精进打卡第107天】 【知~学习】 《六项精进》3遍 共321遍 《大学》3遍 共321...
    亮亮sxm阅读 210评论 0 0