爬虫如何爬取微信公众号文章
因为最近在法院实习,需要一些公众号的数据,然后做成网页展示出来便于查看,之前我倒是写过一些爬虫,但都是爬取网站数据,这次本来以为也会很容易,然而却遇到了不少麻烦,这里和大家分享一下。
1、利用爬虫爬取数据最基本的也是最重要的就是找到目标网站的url地址,然后遍历地址逐个或多线程爬取,一般后续的爬取地址主要通过两种方式获取,一是根据网页的分页,推算出url地址的规律,一般是后面跟着参数page=num,另一种就是筛选出当前页的<a href=“url”>标签,取出url作为后续的爬取地址。很遗憾,这两种方法在微信公众号里都无法使用,原因在于公众号的文章地址之间没有关联,无法通过一篇文章的地址找到所有的文章地址。
2、那我们该如何获取公众号的历史文章地址呢,一种方法是通过搜狗微信网站搜索目标公众号,可以看到最近的一篇文章,但也只是最近的一篇,无法获取历史文章,如果你想做每天的定时爬取,可以采用这种方法,每天爬取一篇。如图是这样的:
3、上面的当然不少我们需要的结果,所以我们还是要想办法把所以的历史文字获取到,废话少说,直切主题:
首先你要注册一个微信公众号(订阅号),可以注册个人的,比较简单,步骤网上都有,这里不做介绍了。(如果之前有就不需要注册了)。
注册好之后,登录微信公众平台,在首页的左边栏的管理下面,有一个素材管理,如图所示:
点击素材管理,然后选择图文消息,再点击右侧的新建图文素材:
跳转到新页面,点击顶部超链接:
然后在弹窗里选择查找文章,输入你要爬取的公众号名称,然后搜索就可以啦:
然后再点击搜索出来的公众号,就可以看到它的所有历史文章了:
4、找到历史文章后我们该如何写程序获取到所有的url地址呢?,首先我们来分析一下点击公众号名称的时候浏览器做了什么,调出检查页面,点击网络,先清除掉所有数据,然后点击目标公众号,可以看到下面界面:
点击那串字符串之后,然后点击headers:
找到General,这里的Request Url就是我们程序需要请求的地址格式,需要我们拼接出来,这里面的参数在下面的Query String Parameters里更加明了:
这些参数的意义很容易理解,唯一需要说明的是fakeid是公众号的唯一标识,每个公众号不一样,如果爬取其他公众号的,只需要更改这个参数就可以了。其中random可以省略。
另一个重要的部分是Request Headers,这里面包含cookie和User-Agent等重要的信息,在接下来的代码中都会用到:
5、上面分析完之后就可以开始写代码了。
首先需要的参数:
# 目标urlurl = 'https://mp.weixin.qq.com/cgi-bin/appmsg'# 使用Cookie,跳过登陆操作headers = { 'Cookie': 'ua_id=YF6RyP41YQa2QyQHAAAAAGXPy_he8M8KkNCUbRx0cVU=; pgv_pvi=2045358080; pgv_si=s4132856832; uuid=48da56b488e5c697909a13dfac91a819; bizuin=3231163757; ticket=5bd41c51e53cfce785e5c188f94240aac8fad8e3; ticket_id=gh_d5e73af61440; cert=bVSKoAHHVIldcRZp10_fd7p2aTEXrTi6; noticeLoginFlag=1; remember_acct=mf1832192%40smail.nju.edu.cn; data_bizuin=3231163757; data_ticket=XKgzAcTceBFDNN6cFXa4TZAVMlMlxhorD7A0r3vzCDkS++pgSpr55NFkQIN3N+/v; slave_sid=bU0yeTNOS2VxcEg5RktUQlZhd2xheVc5bjhoQTVhOHdhMnN2SlVIZGRtU3hvVXJpTWdWakVqcHowd3RuVF9HY19Udm1PbVpQMGVfcnhHVGJQQTVzckpQY042QlZZbnJzel9oam5SdjRFR0tGc0c1eExKQU9ybjgxVnZVZVBtSmVnc29ZcUJWVmNWWEFEaGtk; slave_user=gh_d5e73af61440; xid=93074c5a87a2e98ddb9e527aa204d0c7; openid2ticket_obaWXwJGb9VV9FiHPMcNq7OZzlzY=lw6SBHGUDQf1lFHqOeShfg39SU7awJMxhDVb4AbVXJM=; mm_lang=zh_CN', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36',}data = {'token': '1378111188','lang': 'zh_CN','f': 'json','ajax': '1','action': 'list_ex','begin': '0','count': '5','query': '','fakeid': 'MzU5MDUzMTk5Nw==','type': '9',}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
根据自己的cookie和token进行更改,然后发送请求获取响应,去除每一篇文章的title和url,代码如下:
content_list = []for i in range(20):data['begin'] = i*5time.sleep(3)# 使用get方法进行提交content_json = requests.get(url, headers=headers, params=data).json()# 返回了一个json,里面是每一页的数据for item in content_json['app_msg_list']: # 提取每页文章的标题及对应的urlitems = []items.append(item['title'])items.append(item['link'])content_list.append(items)1234567891011121312345678910111213
第一个for循环是爬取的页数,首先需要看好公众号的历史文章列表一共有多少页,这个数只能小于页数。更改data[“begin”],表示从第几条开始,每次5条,注意爬取不能够太多和太频繁,不然会被封ip封cookie,严重还会封公众号。
然后把title和url保存起来,如下:
name=['title','link']test=pd.DataFrame(columns=name,data=content_list)test.to_csv('XXX.csv',mode='a',encoding='utf-8')print('保存成功')
1
2
3
4
1
2
3
4
完整程序如下:
# -*- coding: utf-8 -*-import requestsimport timeimport csvimport pandas as pd# 目标urlurl = 'https://mp.weixin.qq.com/cgi-bin/appmsg'# 使用Cookie,跳过登陆操作headers = { 'Cookie': 'ua_id=YF6RyP41YQa2QyQHAAAAAGXPy_he8M8KkNCUbRx0cVU=; pgv_pvi=2045358080; pgv_si=s4132856832; uuid=48da56b488e5c697909a13dfac91a819; bizuin=3231163757; ticket=5bd41c51e53cfce785e5c188f94240aac8fad8e3; ticket_id=gh_d5e73af61440; cert=bVSKoAHHVIldcRZp10_fd7p2aTEXrTi6; noticeLoginFlag=1; remember_acct=mf1832192%40smail.nju.edu.cn; data_bizuin=3231163757; data_ticket=XKgzAcTceBFDNN6cFXa4TZAVMlMlxhorD7A0r3vzCDkS++pgSpr55NFkQIN3N+/v; slave_sid=bU0yeTNOS2VxcEg5RktUQlZhd2xheVc5bjhoQTVhOHdhMnN2SlVIZGRtU3hvVXJpTWdWakVqcHowd3RuVF9HY19Udm1PbVpQMGVfcnhHVGJQQTVzckpQY042QlZZbnJzel9oam5SdjRFR0tGc0c1eExKQU9ybjgxVnZVZVBtSmVnc29ZcUJWVmNWWEFEaGtk; slave_user=gh_d5e73af61440; xid=93074c5a87a2e98ddb9e527aa204d0c7; openid2ticket_obaWXwJGb9VV9FiHPMcNq7OZzlzY=lw6SBHGUDQf1lFHqOeShfg39SU7awJMxhDVb4AbVXJM=; mm_lang=zh_CN', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36',}data = {'token': '1378111188','lang': 'zh_CN','f': 'json','ajax': '1','action': 'list_ex','begin': '0','count': '5','query': '','fakeid': 'MzU5MDUzMTk5Nw==','type': '9',}content_list = []for i in range(20):data['begin'] = i*5time.sleep(3)# 使用get方法进行提交content_json = requests.get(url, headers=headers, params=data).json()# 返回了一个json,里面是每一页的数据for item in content_json['app_msg_list']: # 提取每页文章的标题及对应的urlitems = []items.append(item['title'])items.append(item['link'])content_list.append(items)print(i)name=['title','link']test=pd.DataFrame(columns=name,data=content_list)test.to_csv('xingzhengzhifa.csv',mode='a',encoding='utf-8')print('保存成功')1234567891011121314151617181920212223242526272829303132333435363738394041424344454612345678910111213141516171819202122232425262728293031323334353637383940414243444546
最后保存的文件如图:
取到了每一篇文章的url,接下来就可以遍历进行爬取每一篇文章的内容了,关于爬取文章内容的部分将会在下一篇博客中介绍。
补充内容:
关于有小伙伴问到如何获取文章封面图和摘要的问题,检查浏览器时可以看到返回的json数据中包含很多信息,里面就有封面图和摘要
只需要 items.append(item[“digest”])就可以保存文章摘要了。其他字段如发布时间都可以获取。
关于获取阅读量和点赞数的问题,通过本问的方式是没办法获取的,因为网页打开公众号文章是没有阅读数和点赞数的,这个需要使用电脑版微信或手机版微信利用抓包工具获取。
关于ip代理,计算页数,多次保存的问题,我在我的公众号里的文章中介绍了,有需要的可以取看一下