python爬虫(一)之 抓取极氪网站汽车文章

极氪汽车文章爬虫

闲来没事,将极氪网站的汽车文章吃干抹尽,全部抓取到本地,还是有点小小的难度。不能抓取太快,太快容易被封禁IP,不过就算被封了问题也不大,大不了重启路由器,然后你的IP里面又是一条好汉,又可以在网络随心所欲地抓取数据。

import random
import requests
import json
import csv
from lxml import etree
import time
import base64
import re
from Crypto.Cipher import AES

"""
极氪爬虫逆向

https://blog.csdn.net/2301_79445611/article/details/133840084

"""


class Kr36:

    def __init__(self):
        self.article_list_pre_url = "https://gateway.36kr.com/api/mis/nav/ifm/subNav/flow"

        self.start_page = 1
        self.end_page = 1000
        self.init_page_callback = "eyJmaXJzdElkIjo0NTIzNzYyLCJsYXN0SWQiOjQ1MjIzOTAsImZpcnN0Q3JlYXRlVGltZSI6MTcxMDQxODU0MjA2NywibGFzdENyZWF0ZVRpbWUiOjE3MTAzMjk5MTM0MTl9"
        self.payload = json.dumps({
            "partner_id": "web",
            "timestamp": 1710253726028,
            "param": {
                "subnavType": 1,
                "subnavNick": "travel",
                "pageSize": 30,
                "pageEvent": 1,
                "pageCallback": "eyJmaXJzdElkIjo0NTE5NDg3LCJsYXN0SWQiOjQ1MTc1NzksImZpcnN0Q3JlYXRlVGltZSI6MTcxMDEzMDE5OTM4MywibGFzdENyZWF0ZVRpbWUiOjE3MDk4NTUyMzkxMzl9",
                "siteId": 1,
                "platformId": 2
            }
        })

        self.article_list_headers = {
            'Accept': '*/*',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'Cookie': 'sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2218e330f24e210f-09e7e5136418ef-26001b51-1821369-18e330f24e3257b%22%2C%22%24device_id%22%3A%2218e330f24e210f-09e7e5136418ef-26001b51-1821369-18e330f24e3257b%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_referrer_host%22%3A%22%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%7D%7D; tfstk=enSMvVNZXN8175m5p1K_xdJHfjzdCftXwsnvMnd48BRIbq59kwAcT6ANBtefiE5dimB9XtCng_CY1EesXI5HfMQtDCF6mt5Jm7F82uB1CIt4w7CpcU8wcEV4JbERCOMEIjyR8unD7DJAc9HIGUqPYrLyZYLloFBmJpdPQCWOBMl2-V69tFYhAdXHaOur0mSHIFjrr2urNOnXL-IElqTwdpARo9nzs4osO423K4Ze7p9_xJ2nlqTwdpA8KJ0r8FJBCkf..; Hm_lvt_1684191ccae0314c6254306a8333d090=1710253616,1710345937,1710421835; Hm_lvt_713123c60a0e86982326bae1a51083e1=1710253616,1710345937,1710421835; aliyungf_tc=4c273ea1e0ec1ba7c726c1d40e9f785731cff0f77ce5ac27f88ffeb1a6079cab; acw_tc=1a0c398517104218376678635e141118f68f5ec0ce2ac3421247f3e3c09817; Hm_lpvt_1684191ccae0314c6254306a8333d090=1710421897; Hm_lpvt_713123c60a0e86982326bae1a51083e1=1710421897',
            'Origin': 'https://36kr.com',
            'Referer': 'https://36kr.com/',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-site',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
            'sec-ch-ua': '"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"Windows"'
        }

        self.article_detail_headers = {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Cache-Control': 'max-age=0',
            'Connection': 'keep-alive',
            'Cookie': 'sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2218e330f24e210f-09e7e5136418ef-26001b51-1821369-18e330f24e3257b%22%2C%22%24device_id%22%3A%2218e330f24e210f-09e7e5136418ef-26001b51-1821369-18e330f24e3257b%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_referrer_host%22%3A%22%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%7D%7D; tfstk=enSMvVNZXN8175m5p1K_xdJHfjzdCftXwsnvMnd48BRIbq59kwAcT6ANBtefiE5dimB9XtCng_CY1EesXI5HfMQtDCF6mt5Jm7F82uB1CIt4w7CpcU8wcEV4JbERCOMEIjyR8unD7DJAc9HIGUqPYrLyZYLloFBmJpdPQCWOBMl2-V69tFYhAdXHaOur0mSHIFjrr2urNOnXL-IElqTwdpARo9nzs4osO423K4Ze7p9_xJ2nlqTwdpA8KJ0r8FJBCkf..; aliyungf_tc=c8a95eb5a40ff7daafa6a84507110db651dad31ea165d934af3ec32b3f6514cf; acw_tc=ac11000117104218364426625e82f18159f99e101f9e32e840da085962de21; Hm_lvt_1684191ccae0314c6254306a8333d090=1710253616,1710345937,1710421835; Hm_lvt_713123c60a0e86982326bae1a51083e1=1710253616,1710345937,1710421835; Hm_lpvt_1684191ccae0314c6254306a8333d090=1710421976; Hm_lpvt_713123c60a0e86982326bae1a51083e1=1710421976; SERVERID=6754aaff36cb16c614a357bbc08228ea|1710421983|1710421837',
            'Sec-Fetch-Dest': 'document',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Site': 'same-origin',
            'Sec-Fetch-User': '?1',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
            'sec-ch-ua': '"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"Windows"'
        }

        self.cookies = {
            "sensorsdata2015jssdkcross": "^%^7B^%^22distinct_id^%^22^%^3A^%^2218b2931b25d63d-08aa76c3e8a47a-78505770-1821369-18b2931b25e11b9^%^22^%^2C^%^22^%^24device_id^%^22^%^3A^%^2218b2931b25d63d-08aa76c3e8a47a-78505770-1821369-18b2931b25e11b9^%^22^%^2C^%^22props^%^22^%^3A^%^7B^%^22^%^24latest_traffic_source_type^%^22^%^3A^%^22^%^E7^%^9B^%^B4^%^E6^%^8E^%^A5^%^E6^%^B5^%^81^%^E9^%^87^%^8F^%^22^%^2C^%^22^%^24latest_referrer^%^22^%^3A^%^22^%^22^%^2C^%^22^%^24latest_referrer_host^%^22^%^3A^%^22^%^22^%^2C^%^22^%^24latest_search_keyword^%^22^%^3A^%^22^%^E6^%^9C^%^AA^%^E5^%^8F^%^96^%^E5^%^88^%^B0^%^E5^%^80^%^BC_^%^E7^%^9B^%^B4^%^E6^%^8E^%^A5^%^E6^%^89^%^93^%^E5^%^BC^%^80^%^22^%^7D^%^7D",
            "aliyungf_tc": "87a15f620fd2d71d70704946aa353992ba8148f24a896fdd26a3f2dda630d053",
            "acw_tc": "0a6fd1ef16973374951548793e6f60efb7406e5628b6676540af7b96b8de7d",
            "Hm_lvt_1684191ccae0314c6254306a8333d090": "1697203204,1697337496",
            "Hm_lvt_713123c60a0e86982326bae1a51083e1": "1697203204,1697337496",
            "Hm_lpvt_713123c60a0e86982326bae1a51083e1": "1697337578",
            "Hm_lpvt_1684191ccae0314c6254306a8333d090": "1697337578",
            "SERVERID": "d36083915ff24d6bb8cb3b8490c52181^|1697337581^|1697337496"
        }

    def post_request(self, url, headers, payload):
        response = requests.request("POST", url, headers=headers, data=payload)
        return response.text

    def get_request(self, url, headers, cookies):
        response = requests.get(url, headers=headers, cookies=cookies)
        return response.text

    def do_work(self):
        with open('36kr.csv', 'w', newline='', encoding='utf-8-sig') as file:
            writer = csv.writer(file)
            csv_title = ["标题", "作者", "发布时间", "原文地址", "正文"]
            writer.writerow(csv_title)

            page_no = 1
            pageCallback = self.init_page_callback
            while True:
                print("================> 当前第" + str(page_no) + "页 ============")
                payload = json.dumps({
                    "partner_id": "web",
                    "timestamp": int(round(time.time() * 1000)),
                    "param": {
                        "subnavType": 1,
                        "subnavNick": "travel",
                        "pageSize": 30,
                        "pageEvent": 1,
                        "pageCallback": pageCallback,
                        "siteId": 1,
                        "platformId": 2
                    }
                })
                # seconds = random.randint(30, 60)
                # time.sleep(seconds)
                text = self.post_request(self.article_list_pre_url, headers=self.article_list_headers, payload=payload)
                data = json.loads(text)["data"]
                pageCallback = data["pageCallback"]
                itemList = data["itemList"]
                self.write_page(writer, itemList)

                page_no += 1

    def write_page(self, writer, itemList):
        for item in itemList:
            # print(item["title"])
            # print(item["author"]["username"])
            # print(item["created_at"])
            # 获取文章详情内容
            # https://36kr.com/p/2686487273459590
            article_url = "https://36kr.com/p/" + str(item["itemId"])
            text = self.get_request(article_url, headers=self.article_detail_headers, cookies=self.cookies)

            tree = etree.HTML(text)
            data = tree.xpath('/html/body/script/text()')[0]
            baase64_data = re.findall('.*?state":"(.*?)","', data)[0]
            key = "efabccee-b754-4c".encode('utf-8')
            aes = AES.new(key, AES.MODE_ECB)
            data = aes.decrypt(base64.b64decode(baase64_data))
            decode_date = data.decode()
            replace_data = decode_date[0: decode_date.rfind('}') + 1]
            # print(replace_data)
            json_data = json.loads(replace_data)
            article_detail_data = json_data["articleDetail"]["articleDetailData"]
            # print(article_detail_data)

            time_struct = time.localtime(int(item["templateMaterial"]["publishTime"] / 1000))
            date = time.strftime("%Y-%m-%d %H:%M:%S", time_struct)

            row = [item["templateMaterial"]["widgetTitle"], item["templateMaterial"]["authorName"], article_url, date,
                   article_detail_data["data"]["widgetContent"]]
            writer.writerow(row)
            seconds = random.randint(20, 60)
            print("===========> 当前文章 " + article_url + " 写入完毕,等待" + str(seconds) + "秒继续")
            time.sleep(seconds)


if __name__ == '__main__':
    kr36 = Kr36()
    kr36.do_work()

上面即为爬虫代码,拿到代码之后可能没法直接运行,如果运行出错大概的原因可能有如下几种,首先可能为相应的包没有安装,其次可能代码中的cookie已发生过期,这两个问题都比较简单,在此不再赘述。解决上面的问题之后即可直接运行代码,耐心的登上个一段时间,就可以拿到你想要的数据啦。

最终生成的文件为一个CSV文件,名称为36kr.csv,存放在当前目录下。

运行效果

写在最后

代码精选(www.codehuber.com),程序员的终身学习网站已上线!

如果这篇【文章】有帮助到你,希望可以给【JavaGPT】点个赞👍,创作不易,如果有对【后端技术】、【前端领域】感兴趣的小可爱,也欢迎关注❤️❤️❤️ 【JavaGPT】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💝💝💝!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/596002.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

谷歌明年6月关闭 Google Fit 运动记录API,要求开发者迁移至Android Health平台 | 最新快讯

5 月 6 日消息,谷歌近日发布官方新闻稿,宣布将在明年 6 月使用 Android Health 平台取代 Google Fit 运动记录 API,开发人员应当尽早启动迁移计划。 谷歌自 2022 年起逐渐扩大对 Android Health 平台的投资,旨在减少平台碎片化&am…

在uni-app开发的小程序中引入阿里的多色图标

uniapp不支持阿里多色图标,需要使用工具iconfont-tools进行处理 1.首先 在阿里图标库将 需要的图标添加到项目中 并下载压缩包,取出iconfont.js文件 2.安装iconfont-tools,安装完成会显示出安装到了电脑的那个目录 3,进入目录就会看到下面的…

Maria DB 安装(含客户端),看这一篇就够了

文章目录 一 安装前准备1 版本与Win平台对应2 推荐安装 二 安装步骤1 安装主体程序2 添加系统路径Path 三 客户端 一 安装前准备 1 版本与Win平台对应 版本对应关系可参考: https://www.codebye.com/mariadb-deprecated-package-platforms.html。 2 推荐安装 经…

STM32F4xx开发学习—GPIO

GPIO 学习使用STM32F407VET6GPIO外设 寄存器和标准外设库 1. 寄存器 存储器映射 存储器本身是不具有地址的,是一块具有特定功能的内存单元,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程就叫做存储区映射。给内存单元分配地址之后…

spring高级篇(十)

1、内嵌tomcat boot框架是默认内嵌tomcat的,不需要手动安装和配置外部的 Servlet 容器。 简单的介绍一下tomcat服务器的构成: Catalina: Catalina 是 Tomcat 的核心组件,负责处理 HTTP 请求、响应以及管理 Servlet 生命周期。它包…

excel中数据筛选技巧

1、筛选excel中破折号前后都为空的数据 在Excel中查找破折号前后为空的数据,你可以结合使用Excel的查找和筛选功能,或者利用一些公式来判断。以下是两种常用的方法: 方法一:使用筛选功能选中数据范围:首先&#xff0c…

题目:排序疑惑

问题描述: 解题思路: 做的时候没想到,其实这是以贪心题。我们可以每次排最大的区间(小于n,即n-1大的区间),再判断是否有序 。因此只需要分别判断排(1~n-1)和(…

GateWay检查接口耗时

添加gateway依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency>创建一个LogTimeGateWayFilterFactory类&#xff0c;可以不是这个名字但是后面必须是x…

遭遇.halo勒索病毒怎么办?如何识别和应对.halo勒索病毒

导言&#xff1a; 近年来&#xff0c;网络安全问题愈发严峻&#xff0c;其中勒索病毒成为了威胁企业和个人数据安全的重要隐患。在2023年初&#xff0c;一种新的勒索病毒——.halo勒索病毒开始在网络上肆虐&#xff0c;给广大用户带来了极大的困扰。本文91数据恢复将对.halo勒…

NEO 学习之session7

文章目录 选项 A&#xff1a;它涉及学习标记数据。 选项 B&#xff1a;它需要预定义的输出标签进行训练。 选项 C&#xff1a;它涉及在未标记的数据中寻找模式和关系。 选项 D&#xff1a;它专注于根据输入-输出对进行预测。 答案&#xff1a;选项 C 描述了无监督学习的本质&am…

【Pytorch】2.TensorBoard的运用

什么是TensorBoard 是一个可视化和理解深度爵溪模型的工具。它可以通过显示模型结构、训练过程中的指标和图形化展示训练的效果来帮助用户更好地理解和调试他们的模型 TensorBoard的使用 安装tensorboard环境 在终端使用 conda install tensorboard通过anaconda安装 导入类Sum…

判断dll/lib是32/64位、查看lib是导入库/静态库的方法 、查看dll包含的符合、lib包含的函数

一、判断dll/lib是32/64位 原文链接&#xff1a;https://www.cnblogs.com/bandaoyu/p/16752602.html 1. 简便方法&#xff1a; 直接用记事本或者notepad(或txt文本)打开exe文件&#xff08;dll文件&#xff09;&#xff0c;会有很多乱码&#xff0c;不要头疼&#xff0c;接下…

【统计推断】-01 抽样原理之(三)

文章目录 一、说明二、抽样分布三 均值抽样分布3.1 有限母体无放回抽样3.2 有限母体有放回抽样3.3 无限母体 四、比例抽样分布五、和差抽样分布 一、说明 上文中叙述母体和抽样的设计&#xff1b;以及抽样分布的概念&#xff0c;本篇将这种关系定量化&#xff0c;专门针对抽样的…

jmeter后置处理器提取到的参数因为换行符导致json解析错误

现象&#xff1a; {"message":"JSON parse error: Illegal unquoted character ((CTRL-CHAR, code 10)): has to be escaped using backslash to be included in string value; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Ill…

ModuleNotFoundError: No module named ‘pkg_resources‘ 问题如何解决?

ModuleNotFoundError: No module named pkg_resources 通常是因为 Python 环境中缺少 setuptools 模块。pkg_resources 是 setuptools 包的一部分&#xff0c;用于处理 Python 包的发行和资源。 为解决这个问题&#xff0c;请按照以下步骤操作&#xff1a; 确保 setuptools 已…

Pytorch基础:内置类type的用法

相关阅读 Pythonhttps://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 在python中&#xff0c;一切数据类型都是对象&#xff08;即类的实例&#xff09;&#xff0c;包括整数、浮点数、字符串、列表、元组、集合、字典、复数、布尔、函数、…

websevere服务器从零搭建到上线(四)|muduo网络库的基本原理和使用

文章目录 muduo源码编译安装muduo框架讲解muduo库编写服务器代码示例代码解析用户连接的创建和断开回调函数用户读写事件回调 使用vscode编译程序配置c_cpp_properties.json配置tasks.json配置launch.json编译 总结 muduo源码编译安装 muduo依赖Boost库&#xff0c;所以我们应…

npy文件如何追加数据?

.npy 文件是 NumPy 库用于存储数组数据的二进制格式&#xff0c;它包含一个描述数组结构的头部信息和实际的数据部分。直接追加数据到现有的 .npy 文件并不像文本文件那样直接&#xff0c;因为需要手动修改文件头部以反映新增数据后的数组尺寸&#xff0c;并且要确保数据正确地…

【哈希表】Leetcode 14. 最长公共前缀

题目讲解 14. 最长公共前缀 算法讲解 我们使用当前第一个字符串中的与后面的字符串作比较&#xff0c;如果第一个字符串中的字符没有出现在后面的字符串中&#xff0c;我们就直接返回&#xff1b;反之当容器中的所有字符串都遍历完成&#xff0c;说明所有的字符串都在该位置…

从简单逻辑到复杂计算:感知机的进化与其在现代深度学习和人工智能中的应用(上)

文章目录 引言第一章&#xff1a;感知机是什么第二章&#xff1a;简单逻辑电路第三章&#xff1a;感知机的实现3.1 简单的与门实现3.2 导入权重和偏置3.3 使用权重和偏置的实现实现与门实现与非门和或门 文章文上下两节 从简单逻辑到复杂计算&#xff1a;感知机的进化与其在现代…
最新文章