python 爬取今日头条热点新闻

嗯,今天就让我们来一起爬爬今日头条的热点新闻吧!

今日头条地址https://www.toutiao.com/ch/news_hot/

在浏览器中打开今日头条的链接,选中左侧的热点,在浏览器开发者模式,network下很快能找到一个‘?category=new_hot…’字样的文件,点击进去就能看到请求地址了。如下图:

在这里插入图片描述
该请求地址的数据全部存放在data 字段中,并且数据类型为json。如下图
在这里插入图片描述
请求的链接地址为:

https://www.toutiao.com/api/pc/feed/?category=news_hot&utm_source=toutiao&widen=1&max_behot_time=1577347347&max_behot_time_tmp=1577347347&tadrequire=true&as=A1450EF0A468003&cp=5E04F850E003EE1&_signature=VYMs9gAgEBe5v1fEUcnQ31WDLeAAAuI

其中有9个参数,对比如下表:
在这里插入图片描述
其中max_behot_time在获取的json数据中获得,具体数据见如下截图:
在这里插入图片描述
请求地址中,有两个参数as和cp,都是经过js加密处理过。不过也有相对应的加密算法:

加密算法:
var e = {};
    e.getHoney = function() {
        var t = Math.floor((new Date).getTime() / 1e3),
            e = t.toString(16).toUpperCase(),
            n = md5(t).toString().toUpperCase();
        if (8 != e.length) return {
            as: "479BB4B7254C150",
            cp: "7E0AC8874BB0985"
        };
        for (var o = n.slice(0, 5), i = n.slice(-5), a = "", r = 0; 5 > r; r++) a += o[r] + e[r];
        for (var l = "", s = 0; 5 > s; s++) l += e[s + 3] + i[s];
        return {
            as: "A1" + a + e.slice(-3),
            cp: e.slice(0, 3) + l + "E1"
        }
    }, t.ascp = e
}(window, document), function() {
    var t = ascp.getHoney(),
        e = {
            path: "/",
            domain: "i.snssdk.com"
        };
    $.cookie("cp", t.cp, e), $.cookie("as", t.as, e), window._honey = t
}(), Flow.prototype = {
    init: function() {
        var t = this;
        this.url && (t.showState(t.auto_load ? NETWORKTIPS.LOADING : NETWORKTIPS.HASMORE), this.container.on("scrollBottom", function() {
            t.auto_load && (t.lock || t.has_more && t.loadmore())
        }), this.list_bottom.on("click", "a", function() {
            return t.lock = !1, t.loadmore(), !1
        }))
    },
    loadmore: function(t) {
        this.getData(this.url, this.type, this.param, t)
    },

python获取as和cp值的代码如下:

参考博客:https://www.cnblogs.com/xuchunlin/p/7097391.html

import time
import hashlib 

def get_as_cp_args():
    zz ={}
    now = round(time.time())
    print (now)  # 获取计算机时间
    e = hex(int(now)).upper()[2:]  # hex()转换一个整数对象为十六进制的字符串表示
    print (e)
    i = hashlib.md5(str(int(now)).encode("utf8")).hexdigest().upper() # hashlib.md5().hexdigest()创建hash对象并返回16进制结果
    if len(e)!=8:
        zz = {'as': "479BB4B7254C150",
            'cp': "7E0AC8874BB0985"}
        return zz
    n=i[:5]
    a=i[-5:]
    r = ""
    s = ""
    for i in range(5):
        s = s+n[i]+e[i]
    for j in range(5):
        r = r+e[j+3]+a[j]
    zz = {
            'as': "A1" + s + e[-3:],
            'cp': e[0:3] + r + "E1"
        }
    print (zz)
    return zz

这样完整的链接就构成了,另外提一点就是:_signature参数去掉也是可以获取到json数据的,因此这样请求的链接就完成了。

全部代码如下:

import requests
import json
import time
import hashlib
import xlwt

# 获取as和cp参数的函数
def get_as_cp_args():
    zz ={}
    now = round(time.time())
    print (now)  # 获取计算机时间
    e = hex(int(now)).upper()[2:]  # hex()转换一个整数对象为十六进制的字符串表示
    print (e)
    i = hashlib.md5(str(int(now)).encode("utf8")).hexdigest().upper() # hashlib.md5().hexdigest()创建hash对象并返回16进制结果
    if len(e)!=8:
        zz = {'as': "479BB4B7254C150",
            'cp': "7E0AC8874BB0985"}
        return zz
    n=i[:5]
    a=i[-5:]
    r = ""
    s = ""
    for i in range(5):
        s = s+n[i]+e[i]
    for j in range(5):
        r = r+e[j+3]+a[j]
    zz = {
            'as': "A1" + s + e[-3:],
            'cp': e[0:3] + r + "E1"
        }
    print (zz)
    return zz

#获取解析json后的数据
def get_html_data(target_url):
    # 这里你换成你自己的请求头。直接复制代码,会报错!!!
    headers = {"referer": "https://www.toutiao.com/",
               "accept": "text/javascript, text/html, application/xml, text/xml, */*",
               "content-type": "application/x-www-form-urlencoded",
               "cookie": "tt_webid=6774555886024279565; s_v_web_id=76cec5f9a5c4ee50215b678a6f53dea5; WEATHER24279565; csrftoken=bb8c835711d848db5dc5445604d0a9e9; __tasessionId=gphokc0el1577327623076",
               "user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"}
    response = requests.get(target_url, headers=headers)
    res_data = json.loads(response.text)
    return res_data

# 解析数据,提取相关的字段
def get_parse_data(max_behot_time, base_url, start_url,):
    # 存放所有的今日头条新闻数据
    excel_data = []
    
    # 循环次数,相当于于刷新新闻的次数,正常情况下刷新一次会出现10条新闻,但也存在少于10条的情况;所以最后的结果并不一定是10的倍数
    for i in range(3):
        # 获取as和cp参数的函数
        as_cp_args = get_as_cp_args()  
        # 拼接请求路径地址
        targetUrl = start_url + max_behot_time + '&max_behot_time_tmp=' + max_behot_time + '&tadrequire=true&as=' + as_cp_args['as'] + '&cp=' + as_cp_args['cp']
        res_data = get_html_data(targetUrl)
        time.sleep(1)
        toutiao_data = res_data['data']
        for i in range(len(toutiao_data)):
            toutiao = []
            toutiao_title = toutiao_data[i]['title']                            # 头条新闻标题
            toutiao_source_url = toutiao_data[i]['source_url']                  # 头条新闻链接
            if "https" not in toutiao_source_url:
                toutiao_source_url = base_url + toutiao_source_url
            toutiao_source = toutiao_data[i]['source']                          # 头条发布新闻的来源
            toutiao_media_url = base_url + toutiao_data[i]['media_url']         # 头条发布新闻链接
            toutiao.append(toutiao_title)
            toutiao.append(toutiao_source_url)
            toutiao.append(toutiao_source)
            toutiao.append(toutiao_media_url)
            excel_data.append(toutiao)
            print(toutiao)
    # 获取下一个链接的max_behot_time参数的值
    max_behot_time = str(res_data['next']['max_behot_time'])

    return excel_data

# 数据保存到Excel 表格中中
def save_data(excel_data):
    header = ["新闻标题", "新闻链接", "头条号", "头条号链接"]
    excel_data.insert(0, header)

    workbook = xlwt.Workbook(encoding="utf-8", style_compression=0)
    worksheet = workbook.add_sheet("sheet1", cell_overwrite_ok=True)
    for i in range(len(excel_data)):
        for j in range(len(excel_data[i])):
            worksheet.write(i, j, excel_data[i][j])

    workbook.save(r"今日头条热点新闻.xls")
    print("今日头条新闻保存完毕!!")


if __name__ == '__main__':
    # 链接参数
    max_behot_time = '0'
    # 基础地址
    base_url = 'https://www.toutiao.com'
    # 请求的前半部分地址
    start_url = 'https://www.toutiao.com/api/pc/feed/?category=news_hot&utm_source=toutiao&widen=1&max_behot_time='
    toutiao_data = get_parse_data(max_behot_time, base_url, start_url)
    save_data(toutiao_data)

程序运行结束后Excel表格截图:
在这里插入图片描述

  • 8
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
今日头条爬虫技术说明 ========== 整体思路 -------- 1. 抓取今日头条app的数据包 2. 分析数据包,找出请求的数据(如文章列表,文章url等) 3. 根据文章url等信息,抓取文章内容 4. 若文章中包含视频,则取视频url,然后下载 具体实现 ------ ### 一、抓包 ### 1. 工具:`Fiddler`、 `android`手机、`google浏览器` 2. 步骤: (1)本示例采用[Fiddler](http://fiddler2.com/ "Fiddler")来抓包,安装到电脑,我的电脑是win10 (2)具体配置及使用请见[http://jingyan.baidu.com/article/03b2f78c7b6bb05ea237aed2.html](http://jingyan.baidu.com/article/03b2f78c7b6bb05ea237aed2.html "百度经验") (3)打开今日头条app,开始抓包,抓取到的包如下:![](http://i.imgur.com/fC3y96p.png) (4)经分析得知左侧的json文件及为文章列表,如图![](http://i.imgur.com/I2Z8Iph.png) 如右侧第一个content所指的json文件,文件内容为![](http://i.imgur.com/lwaDLHP.png)此时手机上的信息为 <img src = "http://i.imgur.com/LFSL1AA.png" width = "40%"> 可得上面的结论正确 ### 二、分析 ### 1. 分析所抓到的文章列表数据包:大致分为两类,一类是有视频的文章,一类则是没有视频的文章。 有视频的文章json内容里均有`video_id`这个key,如下图所示:![](http://i.imgur.com/T4hqaIc.png) 2. 没有视频的文章:json文件内容均包含`title`、 `abstract`、 `article_url`等信息,具体内容如下. -------- 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值