最近真的是被 网抑云 这个梗刷爆了,到处都是, 生而为人,我很抱歉,哈哈哈, 碰巧最近学习了一波微信公众号的爬取方式,想试一试, 特地在此献丑了。我是小何, 不定期更新爬虫教学, 其余时间学软件测试和linux中。 八月,继续加油。

目录

资料参考:

工具:

打开fiddle,开始抓包

构造基本参数:

请求网址, 通过json包,分割出标题和网址:

读入本地文件,下载html,转换pdf

打开pdf, 深夜了,打开 ‘网抑云’ 。

全部代码:


关注我哟!!!

资料参考:
本篇博客,基于她的思想之中, 改编于我自己,我自己动手敲了一下, 发现还是存在很大的不同, 也是存在一点问题的, 所以这篇博客,我用我自己的话讲一下这次爬虫的思路,用简单的话说明白。

工具:

import requests
import json
from urllib.parse import urlencode
import pdfkit
# wkhtmltopdf  github : https://github.com/JazzCore/python-pdfkit/wiki/Installing-wkhtmltopdf
import os
import warnings  # 关闭警告

关于pdfkit 这是一个三方库, 它可以将html转换为pdf 或者 image 图像, 他需要一个软件的支持, 就是wkhtmltopdf wkhtmltopdf 官网 说一下, 官网我下了半小时都没动一下, 不知道是不是我个人原因, 推荐还是去第三方网站随便下一个,绝对比这个快!

下载之后, 在 bin 目录下 可以看到 wkhtmltopdf.exe 这个工具,先记下路径,后面需要用到。

打开fiddle,开始抓包


微信公众号的包很好分别的,主要他是一个json包, 而且通过网址我们也可以很好的认出来, 这张截图上注意的点我都标出来了。

其实这也可以理解成一个ajax请求吧, 我们只要构造一个字典参数加入,就可以构造成一个请求网址,这样就可以实现多页爬取了。原理我觉得差不多, 主要还是 构造参数 params 的甄别了,这个很重要, 有些参数没构造成功就不能正确的访问进去。
关于ajax的我也写了一篇博客, 可以进去看看 = =

那下面我们就开始编写爬虫吧!


构造基本参数:

一般我们所讲的基本参数 也就是浏览器的请求头, 还有一些请求参数, cookies之类的, 这里额外加一个 请求参数params , 看代码:
图方便, 这里也可以先构造一个文件 to_pdf
to_pdf.py

# -*- coding :  utf-8 -*-
# @Time      :  2020/8/6  18:31
# @author    :  公众号【测试员小何】
# @Software  :  PyCharm
# @CSDN      :  https://me.csdn.net/qq_45906219
## to_pdf.py# 目标公众号【测试员小何】
biz = 'MzA4NDQwMTczOA=='
# 微信登录后的一些标识参数
pass_ticket = 'DdDXKrOnQztW4p81Nm3nRQQ/EAFMCDz5MZO5KeBYdedjaZPH4nLFHL2LWE1uxHVJ'
appmsg_token = '1073_tnlzQTEqvlr9EgXQdC6zALGHfcJw4By9Bx69bQ~~'
uin = 'Mzc2MDg4MzgxNA=='
key = '360754e56e033319af5321321189d5b230b2bfe570313f76e4ed2ef0cd8a1fcfd087786d9da1d826ed30da55f477215359ba761e2a2af5f92213b05c17d89153631a537e35fc91f6d7fb3009e7113958'
# 安装的wkhtmltopdf.exe文件路径  这个是保存为pdf的 其实他还有保存为文件
wkhtmltopdf_path = r'D:\wkhtmltox\wkhtmltopdf\bin\wkhtmltopdf.exe'

上面提到一些 biz , passticket 之类参数的,我们可以在这里看到。

#公众号【测试员小何】def __init__(self):"""spider the wxChat station"""self.session = requests.session()self.offset = 0  # 偏移量 self.json_name = 'wxChat.json'  # 保存json文件名self.down_path = 'D:/wxChatPDF/'  # 下载地址self.__initGetBaseData()def __initGetBaseData(self):"""input some BaseParams about the requests session"""self.headers = {'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.5;q=0.4',"User-Agent": 这个太长了,在fiddle上面直接复制就可以'X-Requested-With': 'XMLHttpRequest'}self.cookies = {'wxtokenkey': '777',"wxuin": "3760883814","devicetype": "android - 29","version": "27000","lang": "zh_CN","pass_ticket": to_pdf.pass_ticket,"wap_sid2": "COaQqoEOElxramROblROTTRtTktEa29yU3drdExUODg4RjZCaVVsX3lycHV0VUJ""3aWtmMl9xNDlJVFN0YTZJY0NxdzZsTXdfaHJxMmZyTTRUZGlGdTZHNVEtNzh5REVFQUFBfjDDsK / 5BTgNQJVO"}self.profile_url = "https://mp.weixin.qq.com/mp/profile_ext?"self.session.headers.update(self.headers)  # 更新headersself.session.cookies.update(self.cookies)  # 更新cookiesself.params = {'action': 'getmsg','__biz': to_pdf.biz,'f': 'json','offset': '10',  # 若需要多页爬取, 构造 : str(self.offset)'count': '10','is_ok': '1','scene': '124','uin': to_pdf.uin,'key': to_pdf.key,  # 这个好像二十分钟就会失效, 需要隔段时间更换'pass_ticket': to_pdf.pass_ticket,'wxtoken': '','appmsg_token': to_pdf.appmsg_token,'x5': '0',}

这里讲一下 self.profile_url 这个参数, 我们在fiddle上面获得的网址是很长的一段, 其实只要卡到 ? 这里就可以了, 可以试试的。

请求网址, 通过json包,分割出标题和网址:

上面我们构造了一些参数,然后就可以正常的请求网址了,如下:

#公众号【测试员小何】
def run(self):"""提取出标题和网址,保存到json包 然后下载转换为Pdf"""items = {}for jsons in self.get_json():json_list = jsons.get('general_msg_list')json_list = json.loads(json_list)  # 转换为json 类型json_list1 = json_list.get('list')for json_one in json_list1:# 遍历这个列表字典  先解析最外层标题和网址json_list_info = json_one.get('app_msg_ext_info')title = json_list_info.get('title')content_url = json_list_info.get('content_url')items[title] = content_url  # 装入字典json_list_info1 = json_list_info.get('multi_app_msg_item_list')for json_two in json_list_info1:  # 解析第二层标题和网址title2 = json_two.get('title')content_url2 = json_two.get('content_url')items[title2] = content_url2# 转换字典类型items_json = json.dump(items, ensure_ascii=False, indent=4,fp=self.json_name)  # ensure_ascii=False(输出中文), indent=4(缩进为4)# 先写入文件,避免占用太多内存消耗with open(self.json_name, 'a+', encoding='utf-8') as fw:fw.write(items_json)print('dump the wxChat.json is successful!')# 下载ok之后, 就开始下载self.down()def get_json(self):"""得到所有文章的链接构造一个office偏移量 不断的请求构造网址 分析Json包"""print('【ps】 spider the wxChart is starting!')for i in range(1, 2):print(f'The SpiderDemo is spider doing {i} pages')# self.offset += 10 * i  # 开启这个 表示 多页爬取# 对比了很多次 构造网址 和 原网址 还是有很多的区别 在这里改一改才能正确的成功self.profile_url += (urlencode(self.params) + '&f=json HTTP/1.1')self.profile_url = self.profile_url.replace('%3D%3D&f=json', '==&f=json', 1)r = self.session.get(self.profile_url, verify=False)yield r.json()

这里发现了一个很大的问题, 不管是在 get() 里面构造字典, 还是先构造字典,都发现我不能正确的获取到数据, 最后打印了一下构造网址, 发现存在很大问题。

我构造的
https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz=MzA4NDQwMTczOA%3D%3D&f=json&offset=10&count=10&is_ok=1&scene=124&uin=Mzc2MDg4MzgxNA%3D%3D&key=9a979acccbefb6032e6ea1a3ed3fbe82a67e7244eb884c9b4fd497550577b4c57f82cb7c0998ef8dc91cf1dca069ca16fe8cce902f238a72294726745094a68c5efb99f91df5e2592c7540ec90d5b09b&pass_ticket=DdDXKrOnQztW4p81Nm3nRQQ%2FEAFMCDz5MZO5KeBYdedjaZPH4nLFHL2LWE1uxHVJ&wxtoken=&appmsg_token=1073_tnlzQTEqvlr9EgXQdC6zALGHfcJw4By9Bx69bQ~~&x5=0&f=json

从fiddle上面复制的
https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz=MzA4NDQwMTczOA==&f=json&offset=10&count=10&is_ok=1&scene=124&uin=Mzc2MDg4MzgxNA%3D%3D&key=9a979acccbefb6032e6ea1a3ed3fbe82a67e7244eb884c9b4fd497550577b4c57f82cb7c0998ef8dc91cf1dca069ca16fe8cce902f238a72294726745094a68c5efb99f91df5e2592c7540ec90d5b09b&pass_ticket=D2Ir2BvSw4lli9ZReGdqnsFacl0N6Lnpmj9h4EE4CBdqV7cd7co7eRRnOBO4EsG%2F&wxtoken=&appmsg_token=1073_o%252FrQqQ5kpRJZNWMKabr8tLelugCSKx8mIN5IGQ~~&x5=0&f=json HTTP/1.1

对比了一下,发现我自己的url 第一个 == 变成了 %3D%3D , 后缀也少了很多。然后进行了修改, 最后成功进入了。
如下:

#公众号【测试员小何】
self.profile_url += (urlencode(self.params) + '&f=json HTTP/1.1')
self.profile_url = self.profile_url.replace('%3D%3D&f=json', '==&f=json', 1)

上面的代码包括很多json的拆分, 这个我推荐一个网址, 很好用。

可以在线解析 json 包, 在线解析json

读入本地文件,下载html,转换pdf

上面我们代码中讲到, 为了减少内存的占用, 我把文件先保存到本地了,那么现在就可以直接读取本地文件,代码如下:

#公众号【测试员小何】
def pathisok(self, path):"""判断目录是否存在, 不存在就创建 进入文件"""if not os.path.exists(self.down_path):os.mkdir(self.down_path)def down(self):"""打开json包,根据标题,网址开始下载,爬取之后保存的格式可以很多种,这里我使用一下之前学到的一个新工具 to_pdf将网页转换为html页面"""self.pathisok(self.down_path)with open(self.json_name, 'r', encoding='utf-8') as fr:for index in fr:if ':' in index:  # 判断是否是不是标题和网址title = index.strip().split(':')[0]url = ''.join(index.strip().split(':')[1:]).strip(',')# 对网址进一步处理url = url.replace('http', 'https:')# 如果不修改文件名称 一定会报错 OsError的错误 找了很久title = title.replace('\\', '').replace('/', '').replace(':', '').replace(':', '') \.replace('*', '').replace('?', '').replace('?', '').replace('“', '') \.replace('"', '').replace('<', '').replace('>', '').replace('|', '_')print('- ' * 40)print(f'The title is {title} starting spider')print('- ' * 40)# print(os.path.join(self.down_path, title + '.pdf'))pdfkit.from_url(url, os.path.join(self.down_path, title + '.pdf'),configuration=pdfkit.configuration(wkhtmltopdf=to_pdf.wkhtmltopdf_path))# pdfkit.from_url(value, os.path.join(self.savedir, key + '.pdf'),#                 configuration=pdfkit.configuration(wkhtmltopdf=self.cfg.wkhtmltopdf_path))print('- ' * 40)print(f'The title is {title} spider is successful')print('- ' * 40)else:pass

这里要注意一点的, 关于文件的名称,有的时候爬虫我们给文件起名称不会在意很多细节, 如果文件名中有特殊符号, 或者其他不允许的符号,那么创建文件或者目录就会报错, 大致就是IOError 之类的错误了。 所以我们需要对 Title 进行再一次的修改, 确保不会出现问题。

打开pdf, 深夜了,打开 ‘网抑云’ 。

好了, 这就是本次爬虫的全部过程了。

全部代码:

如果对软件测试有兴趣,想了解更多的测试知识,解决测试问题,以及入门指导,
帮你解决测试中遇到的困惑,我们这里有技术高手。如果你正在找工作或者刚刚学校出来,
又或者已经工作但是经常觉得难点很多,觉得自己测试方面学的不够精想要继续学习的,
想转行怕学不会的,都可以加入我们644956177或者关注公众号【测试员小何】领取资料哦~。
群内可领取最新软件测试大厂面试资料和Python自动化、接口、框架搭建学习资料!

# -*- coding :  utf-8 -*-
# @Time      :  2020/8/6  17:00
# @author    : 公众号【测试员小何】
# @Software  :  PyCharm
# @CSDN      :  https://me.csdn.net/qq_45906219
import requests
import json
from urllib.parse import urlencode
import pdfkit
# wkhtmltopdf  github : https://github.com/JazzCore/python-pdfkit/wiki/Installing-wkhtmltopdf
import os
import warningswarnings.filterwarnings('ignore')class wxChatSpider(object):def __init__(self):"""spider the wxChat station"""self.session = requests.session()self.offset = 0self.json_name = 'wxChat.json'self.down_path = 'D:/wxChatPDF/'  # 下载地址self.__initGetBaseData()def run(self):"""提取出标题和网址,保存到json包 然后下载转换为Pdf"""items = {}for jsons in self.get_json():json_list = jsons.get('general_msg_list')json_list = json.loads(json_list)  # 转换为json 类型json_list1 = json_list.get('list')for json_one in json_list1:# 遍历这个列表字典  先解析最外层标题和网址json_list_info = json_one.get('app_msg_ext_info')title = json_list_info.get('title')content_url = json_list_info.get('content_url')items[title] = content_url  # 装入字典json_list_info1 = json_list_info.get('multi_app_msg_item_list')for json_two in json_list_info1:  # 解析第二层标题和网址title2 = json_two.get('title')content_url2 = json_two.get('content_url')items[title2] = content_url2# 转换字典类型items_json = json.dump(items, ensure_ascii=False, indent=4,fp=self.json_name)  # ensure_ascii=False(输出中文), indent=4(缩进为4)# 先写入文件,避免占用太多内存消耗with open(self.json_name, 'a+', encoding='utf-8') as fw:fw.write(items_json)print('dump the wxChat.json is successful!')# 下载ok之后, 就开始下载self.down()def get_json(self):"""得到所有文章的链接构造一个office偏移量 不断的请求构造网址 分析Json包"""print('【ps】 spider the wxChart is starting!')for i in range(1, 2):print(f'The SpiderDemo is spider doing {i} pages')# self.offset += 10 * i  # 开启这个 表示 多页爬取# 对比了很多次 构造网址 和 原网址 还是有很多的区别 在这里改一改才能正确的成功self.profile_url += (urlencode(self.params) + '&f=json HTTP/1.1')self.profile_url = self.profile_url.replace('%3D%3D&f=json', '==&f=json', 1)r = self.session.get(self.profile_url, verify=False)yield r.json()def pathisok(self, path):"""判断目录是否存在, 不存在就创建 进入文件"""if not os.path.exists(self.down_path):os.mkdir(self.down_path)def down(self):"""打开json包,根据标题,网址开始下载,爬取之后保存的格式可以很多种,这里我使用一下之前学到的一个新工具 to_pdf将网页转换为html页面"""self.pathisok(self.down_path)with open(self.json_name, 'r', encoding='utf-8') as fr:for index in fr:if ':' in index:  # 判断是否是不是标题和网址title = index.strip().split(':')[0]url = ''.join(index.strip().split(':')[1:]).strip(',')# 对网址进一步处理url = url.replace('http', 'https:')# 如果不修改文件名称 一定会报错 OsError的错误 找了很久title = title.replace('\\', '').replace('/', '').replace(':', '').replace(':', '') \.replace('*', '').replace('?', '').replace('?', '').replace('“', '') \.replace('"', '').replace('<', '').replace('>', '').replace('|', '_')print('- ' * 40)print(f'The title is {title} starting spider')print('- ' * 40)# print(os.path.join(self.down_path, title + '.pdf'))pdfkit.from_url(url, os.path.join(self.down_path, title + '.pdf'),configuration=pdfkit.configuration(wkhtmltopdf=to_pdf.wkhtmltopdf_path))# pdfkit.from_url(value, os.path.join(self.savedir, key + '.pdf'),#                 configuration=pdfkit.configuration(wkhtmltopdf=self.cfg.wkhtmltopdf_path))print('- ' * 40)print(f'The title is {title} spider is successful')print('- ' * 40)else:passdef __initGetBaseData(self):"""input some BaseParams about the requests session"""self.headers = {'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.5;q=0.4',"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36"" (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36 QBCore/4.0.1301.400 ""QQBrowser/9.0.2524.400 Mozilla/5.0 (Windows NT 6.1; WOW64)"" AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2875.116"" Safari/537.36 NetType/WIFI MicroMessenger/7.0.5 WindowsWechat",'X-Requested-With': 'XMLHttpRequest'}self.cookies = {'wxtokenkey': '777',"wxuin": "3760883814","devicetype": "android - 29","version": "27000","lang": "zh_CN","pass_ticket": to_pdf.pass_ticket,"wap_sid2": "COaQqoEOElxramROblROTTRtTktEa29yU3drdExUODg4RjZCaVVsX3lycHV0VUJ""3aWtmMl9xNDlJVFN0YTZJY0NxdzZsTXdfaHJxMmZyTTRUZGlGdTZHNVEtNzh5REVFQUFBfjDDsK / 5BTgNQJVO"}self.profile_url = "https://mp.weixin.qq.com/mp/profile_ext?"self.session.headers.update(self.headers)  # 更新headersself.session.cookies.update(self.cookies)  # 更新cookiesself.saveDir = 'D:/wxChatSpider'self.params = {'action': 'getmsg','__biz': to_pdf.biz,'f': 'json','offset': '10',  # 若需要多页爬取, 构造 : str(self.offset)'count': '10','is_ok': '1','scene': '124','uin': to_pdf.uin,'key': to_pdf.key,  # 这个好像二十分钟就会失效, 需要隔段时间更换'pass_ticket': to_pdf.pass_ticket,'wxtoken': '','appmsg_token': to_pdf.appmsg_token,'x5': '0',}if __name__ == '__main__':import to_pdf# 里面是第三方库的配置, 以及一些微信公众号的参数spider = wxChatSpider()spider.run()

生而为人,我很抱歉!深夜爬虫, 我很抱歉 ,附微信 “ 网抑云” 公众号爬虫教程!相关推荐

  1. 深夜爬虫, 我很抱歉 , 附微信 “ 网抑云” 公众号爬虫教程!

    最近真的是被 网抑云 这个梗刷爆了,到处都是, 生而为人,我很抱歉,哈哈哈, 碰巧最近学习了一波微信公众号的爬取方式,想试一试, 特地在此献丑了.我是沙漏, 不定期更新爬虫教学, 其余时间学java和 ...

  2. 深夜爬虫, 我很抱歉 , 附爬取“网抑云”最详细的爬虫教程!

    最近真的是被 网抑云 这个梗刷爆了,到处都是, 生而为人,我很抱歉,哈哈哈, 碰巧最近学习了一波微信公众号的爬取方式,想试一试, 特地在此献丑了.我是沙漏, 不定期更新爬虫教学, 其余时间学java和 ...

  3. 基于Python实现微信公众号爬虫进行数据分析

    学爬虫有什么用 网络爬虫是一个非常注重实践性而且实用性很强的编程技能,它不是程序员的专属技能,任何具有一定编程基础的人都可以学习爬虫,写爬虫分析股票走势,上链家爬房源分析房价趋势,爬知乎.爬豆瓣.爬新 ...

  4. 微信公众号爬虫项目(reptile)

    代码仓库地址:reptile: 爬虫项目,微信公众号文章爬虫,网站文章爬虫,群发邮件系统 项目背景 个人在业余时间,写的一个以微信公众号爬虫为主要功能,普通网页爬虫.浏览器控制.邮件群发功能为辅的简单 ...

  5. python 公众号爬虫_微信公众号文章爬虫

    很多的微信公众号都提供了质量比较高的文章阅读,对于自己喜欢的微信公众号,所以想做个微信公众号爬虫,爬取相关公众号的所有文章.抓取公众号的所有的文章,需要获取两个比较重要的参数.一个是微信公众号的唯一I ...

  6. 【Python爬虫实战】微信公众号爬虫:微信公众号浏览自动化

    本文内容详细介绍微信公众号历史文章自动化浏览脚本的实现,配合服务端对公众号文章数据爬取来实现微信公众号文章数据的采集.服务端爬取实现见:微信公众号爬虫:服务端公众号文章数据采集 背景:在团队的学习方面 ...

  7. 【开源Python爬虫】微信公众号爬虫weixin_crawler开源啦

    作者 | 抽丝剥茧 出品 | 爱迪斯 微信公众号爬虫weixin_crawler开源啦 正式介绍weixin_crawler之前,我准备了两个问题,这两个问题通过weixin_crawler自带的报告 ...

  8. [爬虫]网抑云音乐评论

    [爬虫]网抑云音乐评论 前言 自打开网抑云之后,我久久无法忘记,是它才能带给我内心世界的波涛汹涌.我左手拿起它,右手放下它,一日复一日,我终于完成了<The Spider Of Music-16 ...

  9. 使用搜狗接口对微信公众号爬虫

    搜狗搜索因为有微信公众号搜索的接口,所以通过这个接口就可以实现公众号的爬虫 需要安装几个python的库:selenium,pyquery 还使用到phantomjs.exe,这个需要我们自己去下载, ...

最新文章

  1. mfc 静态框接收tab焦点_目标检测中焦点损失的入门指南
  2. Kotlin1.6.20好用的新特性:多receiver扩展函数,绝不可空类型,并行编译kotlin减少编译时间
  3. englishpod主持人对话文本_英语播客ESLPod学习方法+资源大全|Englishpod和eslpod的区别是什么...
  4. fftw3图片傅里叶变换_DFT-去除图片周期性噪声
  5. db2 迁移mysql,mysql 迁移 db2
  6. 响应性web设计实战总结(二)
  7. MapReduce二次排序
  8. 认识 java JVM虚拟机选项 Xms Xmx PermSize MaxPermSize 区别
  9. php上传文件表单,php中关于普通表单多文件上传的处理方法
  10. C++笔记121023
  11. Thinkphp3.2在IIS中使用ISAPI_Rewrite去除index.php
  12. Wincc 开机自检动态展示
  13. 【智能优化算法】基于融合改进 Logistics 混沌和正弦余弦算子的自适应 t 分布海鸥算法求解单目标优化问题附matlab代码
  14. PyTorch深度学习(18)网络结构LeNet、AlexNet
  15. 小米商城官网(登录页,首页,详情页,我的购物车页,我的订单页,确认订单页)HTML+CSS+JS
  16. Softmax回归及损失函数(李沐深度学习课程、自用)
  17. 【存储】RAID0、RAID1、RAID3、RAID5、RAID6、混合RAID10、混合RAID50
  18. zemax评价函数编辑器_zemax默认评价函数使用方法
  19. 你所不知道的Spring的@Autowired实现细节
  20. 以 VS Code为例,看大型开源项目是如何应用软件工程的?

热门文章

  1. java计时器脚本_在倒数计时器脚本中跳过很多秒
  2. Docker基础学习笔记( 搭建web漏洞检测环境和容器中运行Django项目)
  3. 微信小程序 云开发-答题小程序 demo
  4. 计算机隐藏文件夹无法显示,隐藏文件夹无法显示怎么办【图文教程】
  5. 3D塔防游戏实现 5.2 3D怪物死亡(Feekood语言)
  6. IDEA推送本地代码到新远程git地址
  7. 机器学习-KNN最近邻算法原理及实践
  8. Unity3d实现阿拉伯语适配,不规则特殊字符的处理
  9. C语言常见问题(11):a label can only be part of a statement and a declaration is not a statement
  10. 2021秋招面试经历----硬件工程师