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

news2024/12/23 22:30:43

极氪汽车文章爬虫

闲来没事,将极氪网站的汽车文章吃干抹尽,全部抓取到本地,还是有点小小的难度。不能抓取太快,太快容易被封禁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.coloradmin.cn/o/1646268.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

i.MX 6ULL 裸机 IAR 环境安装

一. IAR 的安装请自行搜索 二. 使用最新版本的 IAR,需要修改 SDK 1. 在 SDK 的 core_ca7.h 加上 #include "intrinsics.h" /* IAR Intrinsics */ 2. debug 时需要修改每个工程下的 ddr_init.jlinkscript,参考链接 Solved: How to conn…

使用C语言实现杨氏矩阵并找出数字

前言 过了五一假期,咋们经过了一个假期的休息,要继续学习了,不能偷懒哦!! 今天让我们来看看如何在一个杨氏矩阵中找出自己想找到的数字。 首先,我们要了解一下杨氏矩阵到底是什么,如果一个矩阵中…

[redis] redis为什么快

1. Redis与Memcached的区别 两者都是非关系型内存键值数据库,现在公司一般都是用 Redis 来实现缓存,而且 Redis 自身也越来越强大了!Redis 与 Memcached 主要有以下不同: (1) memcached所有的值均是简单的字符串,red…

ACPWorkbench_for_BP10

一、菜单 文件菜单包含导入导出所有参数,导出flashbin文件和退出操作。文件菜单显示如下: Import Audio Settings:从音频配置文件中导入音频参数。 Export Audio Settings:将音频设置导出为音频配置文件。 Export Flash Binary Fi…

OpenNJet:下一代云原生应用引擎

OpenNJet:下一代云原生应用引擎 前言一、技术架构二、新增特性1. 透明流量劫持2. 熔断机制3. 遥测与故障注入 三、Ubuntu 发行版安装 OpentNJet1. 添加gpg 文件2. 添加APT 源3. 安装及启动4. 验证 总结 前言 OpenNJet,是一款基于强大的 NGINX 技术栈构建…

设置定位坐标+请按任意键继续

设置定位坐标 目的 在编程和游戏开发中,设置定位坐标的目的是为了确定对象在屏幕或游戏世界中的具体位置。坐标通常由一对数值表示,例如 (x, y),其中 x 表示水平位置,y 表示垂直位置。设置定位坐标的目的包括: 1. **精…

【JavaScript】数据类型转换

JavaScript 中的数据类型转换主要包括两种:隐式类型转换(Implicit Type Conversion)和显式类型转换(Explicit Type Conversion)。 1. 隐式类型转换(自动转换): js 是动态语言&…

CNN笔记详解

CNN(卷积神经网络) 计算机视觉,当你们听到这一概念的是否好奇计算机到底是怎样知道这个图片是什么的呢?为此提出了卷积神经网络,通过卷积神经网络,计算机就可以识别出图片中的特征,从而识别出图片中的物体。看到这里充…

XYCTF2024 RE ez unity 复现

dll依然有加壳 但是这次global-metadata.dat也加密了,原工具没办法用了,不过依然是可以修复的 a. 法一:frida-il2cpp-bridge 可以用frida-il2cpp-bridge GitHub - vfsfitvnm/frida-il2cpp-bridge: A Frida module to dump, trace or hijac…

深度剖析muduo网络库1.1---面试提问(阻塞、非阻塞、同步、异步)

在面试过程中,如果被问到关于IO的阻塞、非阻塞、同步、异步时,我们应该如何回答呢? 结合最近学习的课程,我作出了以下的总结,希望能与大家共同探讨! 先给出 陈硕大神原话:在处理IO的时候&…

存储故障后oracle报—ORA-01122/ORA-01207故障处理---惜分飞

客户存储异常,通过硬件恢复解决存储故障之后,oracle数据库无法正常启动(存储cache丢失),尝试recover数据库报ORA-00283 ORA-01122 ORA-01110 ORA-01207错误 以前处理过比较类似的存储故障case:又一起存储故障导致ORA-00333 ORA-00312恢复存储故障,强制拉库报ORA-600 kcbzib_kcr…

计算机毕设

随着社会和国家的重视,大学对于大学生毕业设计越来越重视。 做软件设计设计方面,前后端分离是必不可少的,代码管理工具,前后端接口测试是项目中必须要用到的工具。做大数据设计方面,主要是要用到爬虫进行数据爬取&…

(二)JSP教程——taglib指令

创建标签文件 首先创建一个Web项目,在webapp/WEB-INF目录下创建一个tags文件夹 在tags文件夹中创建一个oddNumberSum.tag文件,Tag文件时扩展名为.tag的文本文件,其结构和JSP文件非常相似,该文件的目录结构如图所示 创建Tag文件的…

Altium Designer——检查原理图库正确性并生成报告

一、方法: 1.打开原理图库: 2.点击菜单栏的报告选项: 3.选择器件规则检查: 根据需求勾选,一般都是全部勾选: 二、问题: 1.缺少封装会导致什么问题: 1.首先: 封装是…

方法的入栈和出栈

一.作用域问题 1.全局作用域 在全局都能进行访问的变量 var a 10;function fn() {var b 20;return a b;}console.log(fn()); 2.局部的作用域 只能在限定的范围内进行访问 function fn() {var b 20;}console.log(b); b is not defined 打印的结果是b这个变量没用定义 3…

9.Admin后台系统

9. Admin后台系统 Admin后台系统也称为网站后台管理系统, 主要对网站的信息进行管理, 如文字, 图片, 影音和其他日常使用的文件的发布, 更新, 删除等操作, 也包括功能信息的统计和管理, 如用户信息, 订单信息和访客信息等. 简单来说, 它是对网站数据库和文件进行快速操作和管…

Xinlinx FPGA如何降低Block RAM的功耗

FPGA中降低Block RAM的功耗有两种方式,分别是选择合适的写操作模式以及Block RAM的实现算法及综合设置。我们知道对于采用IP核生成对应的RAM时,会有最小面积算法、低功耗算法以及固定原语,但是采用最小功耗算法有时由于级联长度导致无法实现&…

Listview控件的5种视图

在C#中,ListView控件是用于显示和编辑列表数据的常用控件。它可以显示数据项的列表,并允许用户对列表中的数据进行操作。 ListView控件有五种视图模式,分别是: LargeIcon视图:在此视图中,每个数据项都显示…

详解xml-java语言

1.XML在线学习手册 XML 教程 2.XML可以做什么 1.给两个程序之间进行数据通信。现在用的最多的是JSON。 2.给服务器做配置文件。 3.存储复杂的数据关系。 4.还可以充当小型的数据库。 3.书写格式 <?xml version"1.0" encoding"UTF-8" ?> <…

ctfshow web入门 sql注入 web224--web233

web224 扫描后台&#xff0c;发现robots.txt&#xff0c;访问发现/pwdreset.php &#xff0c;再访问可以重置密码 &#xff0c;登录之后发现上传文件 检查发现没有限制诶 上传txt,png,zip发现文件错误了 后面知道群里有个文件能上传 <? _$GET[1]_?>就是0x3c3f3d60245…