国庆期间,我成功用Python爬取了几个公众号的历史文章数据。但是在此之前,我其实和大多数小伙伴一样都是Python零基础小白。

我想,这其中我一定是做对了某些事。
通过这篇文章,我想和你分享,
1)我的思考过程
2)我的完整爬虫过程
文末附微信公众号文章下载工具
1.
为什么我能够把这件事做成?
其实是因为做对了两个维度的努力
1)做对的事情
2)把事情做对
这两个维度本质上是一个关于面积的计算:
把事做成=做对的事情 x 把事情做对
查理芒格说,要“去鱼多的地方捕鱼”。

做对的事情,指的是战略方向的正确。
比如下文我提到用Python来爬取公众号,作为Python零基础小白,我的思考点不是如何从零到一学习Python,而是想着找现成的Python爬取公众号文章的案例来学习,直接复制别人成功的经验。这就是做对的事情,
做大概率正确的事情,不至于多走弯路。
把事情做对,指的是战术层面的执行。比如下文我研究Python爬取公众号文章方法的时候,我把能想到的所有搜索渠道都搜了一遍,把能想到的所有关键词也都组合了一遍。但是我也相信,绝大多数小伙伴用百度搜问题的时候,不到20分钟就放弃了。
我相信这些小伙伴一定没好好学过概率论,因为假如一件事情成功的概率是20%,只要能持续重复14次,就可以把这件事情成功的概率提高到95%。
推导过程如下:
做一次失败的概率为:1-20%=80%=0.8
重复做n次至少有一次成功的概率是95%,就相当于重复做n次每一次都不成功的概率是5%,
重复做n次都不成功:80%^n=1-95%=5%=0.05
n=log(0.8,0.05)=13.42
所以重复做13.42次,你成功的概率能达到95%。
所以正确事情重复做,大概率是会成功的。
下面就来和你分享一下我的解题过程:
所以正确事情重复做,大概率是会成功的。
下面就来和你分享一下我的解题过程:

2.
第一步,澄清问题

1)探究问题的本质
为什么我需要爬取公众号数据?
因为太久没写文章,加上被催稿,于是我决定动笔。
在此之前,我准备先搭建好选题库,因为选题意味着文章受众群体和阅读数据直接挂钩。
如何找到一个好的选题?
最简单有效的方法,就是找竞品账号,看看别人的公众号里,哪些文章火了。那些被验证过的选题,都可以纳入你的选题库。于是问题来了,
我该如何爬取别人公众号的数据?
2)准确的描述问题

问题是落差,是理想结果与现状之间的落差。
我的理想结果:导出竞品账号公众号的历史数据,这里的数据需要包含「标题」、「文章链接」、「阅读数」、「点赞数」、「在看数」。我的现状:并不清楚如何导出这些数据。
第二步,寻找对策
生活中我们所遇到的所有问题都可以囊括成两类问题,一类问题是你见过类似的,但是以前的解决方法无效。一类问题是你从来没有遇见过的,摸不着头脑,没有经验可循。
如何寻找对策?
我们可以运用系统思维来解决问题。
所谓的系统思维,就是通过构建、选择以及改善模型来帮助我们更加高效地表达和思考的思维方式。
对于模型的选择,大致有两种方式,一种方式是选择已有的模型进行使用。但是在实际解决问题的时候,我们很多时候会发现自己找不到一个合适的模型,
那该怎么办呢?
这时候就需要我们自己来构建一个新的模型。最常见的构建模型的方法是采用KJ法
1)进行头脑风暴尽可能的罗列要点2)按照内在的相似性、相关性进行归纳

针对这个故事背景,构建出来的模型无非两个维度,如果有现成的数据就直接用别人的数据,如果实在找不到现成的数据,再考虑自己手动爬取。
「1.找现成的数据」
我想到了几个方案,
01 借助壹伴插件导出公众号历史文章
壹伴是可以直接导出个人公众号的历史数据的,但研究发现,它并不支持导出其他公众号的历史数据。
02 借助第三方公众号数据平台
1) 新榜
搜索公众号-点击进入详情页-点击右上角「内容列表」
能查看历史数据,但是仅支持查看最近7天内的推文,显然也不能满足我的需求。
其他相似平台,如清博大数据、西瓜数据都存在相应的局限。
03 某宝付费
淘宝的主流店铺都支持将公众号文章导出为「Word、PDF、HTML格式」,少部分店铺支持导出为Excel格式,价格普遍在4.9元/1000篇左右。
问了几个店铺都不支持导出阅读量等数据,如果你只需要将文章导出为PDF,淘宝付费无疑是很好的选择。
「2.手动爬取数据」
**01 找可以下载公众号文章的软件 **
这里提到的软件,文末会附获取方式
通过查询【公众号文章】、【下载】等关键词,我成功找到了几个可以下载公众号文章的软件。
1)WeChatDownload

这款软件我几年前用过,可以将文章导出为Word、PDF、HTML格式,并支持下载文章评论,缺点依然是不支持下载文章阅读量等数据,无法导出为Excel格式。
2)微信公众号文章下载器

和WechatDownload类似,由吾爱大神开发,支持将文章导出为Word、PDF、HTML格式,并支持下载文章评论。
3)微信公众号文章搜索导出助手

优点:支持将文章批量导出为Word、PDF、Txt、Excel、HTML,也可以将微信文章中视频、语音、音乐音频、评论留言、文章链接、封面头图。
缺点:软件需要付费,目前会员价格49元/年,获取阅读量、评论数、点赞数、在看数据需要付费调用接口25元/1000次。
如果需要爬取的公众号数量不多,这个方案是可以考虑的。
既然上面的方法都不能完美的满足我的需求,于是我产生了一个大胆的想法,干脆自己手动爬虫。
02手动爬虫
最直接想到的就是用Python进行爬虫,
可是问题在于,我并不会Python呀!
于是又构成了一个新的问题,
1)澄清问题
我的理想结果:借助python爬取公众号数据,数据需要包含「标题」、「文章链接」、「阅读数」、「点赞数」、「在看数」。
我的现状:并不会使用Python进行爬虫
2)寻找对策
上面提到了,对于模型的选择,最直接的方式就是选择已有的模型进行使用。

这里我需要的模型是「Python爬取公众号文章的实操案例」。
我猜测互联网上一定有人用Python爬取过公众号的文章数据,
我需要的并不是从头学习python,
而是从别人的成功案例入手,
研究如何复刻。
果不其然,我在Youtube、知乎、B站、CSDN等平台都找到了很多教程。

第三步,选择对策

根据上文寻找的对策,有好几种方案都可以导出微信文章,但是大部分都无法满足我的定制化需求。
综合考虑,最后选择用「Python爬取公众号文章」。
第四步,解决问题

对这部分爬虫内容不感兴趣的小伙伴可以直接略过....
❶ 搜集Python爬取公众号文章的案例
我猜想你比较好奇的是,我是如何搜到这些内容的?
这里先卖个关子,后文揭晓答案。
❷ 安装Python并配置开发环境
这部分内容其实很容易通过B站搜索到相应的教程,配置Python的开发环境以及安装Pycharm大概2个小时内就可以搞定。
❸ 用Fiddler抓包微信接口
1.登录个人微信公众号后台-新的创作-写新图文进入文章编辑页面
2.鼠标右键-点击「检查」(或者快捷键F12打开开发者模式)-点击超链接-选择你需要爬取数据的公众号

3.在右侧开发者工具中点击「网络」-选择「全部」-然后找到appmsg?action=list_ex&begin=开头的数据包

4.点击appmsg?action=list_ex&begin=在负载里找到「fakied」和「token」,在标头里找到「cookie」和「user-agent」这四个数据是我们需要的。

5.运行Fiddler,打开微信公众号客户端,找到已关注订阅列表,打开该公众号的历史文章页面,并随便点开一篇文章。

6.找到带有mp/getappmsgext?的请求包,在「Params」里找到「Key」、「Pass_ticket」、「appmasg_token」,在「Headers」里找到「Cookie」和「User-Agent」这五个数据也是我们所需要的。

❹ 安装Python的requests库、Workbook库
使用WIN+R,输入‘cmd',进入个人计算机的dos系统,
输入命令'pip install requests',回车,等候电脑安装requests库。
不懂的可以百度,都有详细说明。
❺ 将网页爬取的「fakied」、「token」、「cookie」、「user-agent」值,以及Fiddler爬取的「Key」、「Pass_ticket」、「appmasg_token」、「Cookie」、「User-Agent」值替换进下方代码。
import requestsimport timeimport jsonfrom openpyxl import Workbookimport randomurl = "https://mp.weixin.qq.com/cgi-bin/appmsg"Cookie = "自己的cookies"headers = { "Cookie": Cookie, "User-Agent": "自己的user-agent",}token = "自己公众号的token"#公众号fakeid = "Mzk0NzI5NDc5MA%3D%3D"#公众号对应的idtype = '9'data1 = { "token": token, "lang": "zh_CN", "f": "json", "ajax": "1", "action": "list_ex", "begin": "0", "count": "4", "query": "", "fakeid": fakeid, "type": type,}def getMoreInfo(link): # 获得mid,_biz,idx,sn 这几个在link中的信息 mid = link.split("&")[1].split("=")[1] idx = link.split("&")[2].split("=")[1] sn = link.split("&")[3].split("=")[1] _biz = link.split("&")[0].split("_biz=")[1] pass_ticket = "fiddler中获取"#从fiddler中获取 appmsg_token = "fiddler中获取"#从fiddler中获取 url = "http://mp.weixin.qq.com/mp/getappmsgext"#获取详情页的网址 phoneCookie = "在fiddler中获取" headers = { "Cookie": phoneCookie, "User-Agent": "fiddler中获取" } data = { "is_only_read": "1", "is_temp_url": "0", "appmsg_type": "9", 'reward_uin_count': '0' } params = { "__biz": _biz, "mid": mid, "sn": sn, "idx": idx, "key": "fiddler中获取", "pass_ticket": pass_ticket, "appmsg_token": appmsg_token, "uin": "MTUyNzExNzYy", "wxtoken": "777", } requests.packages.urllib3.disable_warnings() content = requests.post(url, headers=headers, data=data, params=params).json() # print(content["appmsgstat"]["read_num"], content["appmsgstat"]["like_num"]) try: readNum = content["appmsgstat"]["read_num"] print("阅读数:"+str(readNum)) except: readNum = 0 try: likeNum = content["appmsgstat"]["like_num"] print("喜爱数:"+str(likeNum)) except: likeNum = 0 try: old_like_num = content["appmsgstat"]["old_like_num"] print("在读数:"+str(old_like_num)) except: old_like_num = 0 time.sleep(3) # 歇3s,防止被封 return readNum, likeNum,old_like_numdef getAllInfo(url): # 拿一页,存一页 messageAllInfo = [] # begin 从0开始 for i in range(33):#设置爬虫页码 begin = i * 4 data1["begin"] = begin requests.packages.urllib3.disable_warnings() content_json = requests.get(url, headers=headers, params=data1, verify=False).json() time.sleep(random.randint(1, 10)) if "app_msg_list" in content_json: for item in content_json["app_msg_list"]: spider_url = item['link'] readNum, likeNum,old_like_num = getMoreInfo(spider_url) info = { "title": item['title'], "url": item['link'], "readNum": readNum, "likeNum": likeNum, "old_like_num":old_like_num } messageAllInfo.append(info) return messageAllInfodef main(): f = Workbook() # 创建一个workbook 设置编码 sheet = f.active#创建sheet表单 # 写入表头 sheet.cell(row=1, column=1).value = 'title' # 第一行第一列 sheet.cell(row=1, column=2).value = 'url' sheet.cell(row=1, column=3).value = 'readNum(阅读数)' sheet.cell(row=1, column=4).value = 'likeNum(喜爱数)' sheet.cell(row=1, column=5).value = 'old_like_num(在看数)' messageAllInfo = getAllInfo(url)#获取信息 print(messageAllInfo) print(len(messageAllInfo))#输出列表长度 # 写内容 for i in range(1, len(messageAllInfo)+1): sheet.cell(row=i + 1, column=1).value = messageAllInfo[i - 1]['title'] sheet.cell(row=i + 1, column=2).value = messageAllInfo[i - 1]['url'] sheet.cell(row=i + 1, column=3).value = messageAllInfo[i - 1]['readNum'] sheet.cell(row=i + 1, column=4).value = messageAllInfo[i - 1]['likeNum'] sheet.cell(row=i + 1, column=5).value = messageAllInfo[i - 1]['old_like_num'] f.save(u'公众号.xls') # 保存文件if __name__ == '__main__': main()
❻ 运行Python,等待爬取结束。
第五步,复盘归档
虽然问题得到了解决,
但还远没结束。
我们还需要进行一次复盘。
复盘的意义在于从过去获得力量,
来帮助我们更好的面对未来。
通过这次活动,
1)我掌握了用Fiddler和Chalers进行抓包的知识;
2)成功的用Python完成了一个小项目,
获得正反馈后以后学习Python更有动力;
3)掌握了下载公众号文章的几种方法(稀缺的技能往往具备高价值);
4)之后如果需要用Python爬取其他内容例如豆瓣的信息,可以如法炮制。
在研究Python爬虫的过程中,
我还探索了另一种解决问题的方案,
采用无代码爬虫的方式。
这些工具并不能解决该场景提到的问题,
所以我没有展开介绍。
但在进行网页爬虫的时候,
反而会比Python来的更便捷。
上面就是我的解题过程,
你可能还有几个问题想问我,
我一并回答。
1)你可能会觉得,这些操作也太浪费时间了吧?
可是,东西贵不贵,不仅取决于价格,还要看你的收益。
看起来,我这一次解决问题的过程,花费了很多时间,但是我的收获却比别人更巨大。
比如我以前爬虫知乎的时候,
用的是「Web Scraper」这款插件,
但是这次我在探索其他爬虫工具的时候,
我发现「后羿采集器」更好用,这就积累了经验。
成甲老师说“如果我们学习是为了提升自己的认知,形成更准确的决策判断力,那么,花时间在构建更系统的知识体系上,就是非常划算的事情。”
2)你可能会问我,“你是如何找到这些软件,以及Python爬取公众号文章的案例的?”
其实是经验的积累,基于经验的学习,
是对每个人而言最基本、最重要的方式。
你搜索的次数多了,
自然就会知道哪些渠道容易找到好东西。
你每次搜索资料的时候10分钟就搜不下去了,
我却要搜2个小时,你说谁更容易精进搜索技能?
成甲老师在《好好思考》这本书里划分了多元思维模型解决问题的四个层次

这四类不同思维模型的特点各有不同。
第一类,经验技巧型的策略往往源自个人有限的经验总结,
而第二类方法流程型的思维模型往往来自更大样本的归纳提炼,
第三类的学科原理型源于经过科学方法验证的规律,
第四类的哲学视角型是人类理性思辨思考问题的方式。
这四种思考深度没有绝对的高下好坏之分,而是有各自的使用场景。——《好好思考》
经过这次爬虫探索,
我掌握了很多新的技巧和方法,
这都会变成我的个人经验。
但是我把它梳理成一篇文章,
或者绘制成一张流程图这就变成了方法流程,
我可以用这套方法解决更多相似的问题。
对我而言它又属于零边际成本的产品,
所以我可以无限售卖,让它变成我的杠杆。
以上就是本文的全部内容,谢谢你的阅读。
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的
本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决
2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p
ValidPalindromeGivenastring,determineifitisapalindrome,consideringonlyalphanumericcharactersandignoringcases. [#125]Example:"Aman,aplan,acanal:Panama"isapalindrome."raceacar"isnotapalindrome.Haveyouconsiderthatthestringmightbeempty?Thisisagoodquestiontoaskduringaninterview.Forthepurposeofthisproblem
是否可以在PyYAML或Ruby的Psych引擎中禁用创建anchor和引用(并有效地显式列出冗余数据)?也许我在网上搜索时遗漏了一些东西,但在Psych中似乎没有太多可用的选项,而且我也无法确定PyYAML是否允许这样做.基本原理是我必须序列化一些数据并将其以可读的形式传递给一个不是真正的技术同事进行手动验证。有些数据是多余的,但我需要以最明确的方式列出它们以提高可读性(anchor和引用是提高效率的好概念,但不是人类可读性)。Ruby和Python是我选择的工具,但如果有其他一些相当简单的方法来“展开”YAML文档,它可能就可以了。 最佳答案
我很好奇.NET将如何影响Python和Ruby应用程序。用IronPython/IronRuby编写的应用程序是否会非常特定于.NET环境,以至于它们实际上将变得特定于平台?如果他们不使用任何.NET功能,那么IronPython/IronRuby相对于非.NET同类产品的优势是什么? 最佳答案 我不能说任何关于IronRuby的东西,但是大多数Python实现(如IronPython、Jython和PyPy)都试图尽可能忠实于CPython实现。不过,IronPython正在迅速成为这方面的佼佼者之一,并且在PlanetPyth