forest-3821416_640.jpg

版权申明

原创文章:本博所有原创文章,欢迎转载,转载请注明出处,并联系本人取得授权。 版权邮箱地址:banquan@mrdwy.com

简介

我反复试了网上各种方法,都可能已经过时,或者无法使用,我这个办法主要的思路是登陆PC端的微信,然后使用抓包工具,通过获取公众号历史文章记录的接口解析出文章链接,截止本文发布该方法还有效,但不排除微信会修改规则。

先上代码

# # coding:utf-8
import http.cookiejar  
import json  
import time  
from urllib import request

import requests

es_url = 'http://127.0.0.1:9200'  
index = '/wechat/history'  
cookie = http.cookiejar.CookieJar()  # 声明一个CookieJar对象实例来保存cookie  
handler = request.HTTPCookieProcessor(cookie)  # 利用urllib2库的HTTPCookieProcessor对象来创建cookie处理器  
opener = request.build_opener(handler)  # 通过handler来构建opener  
headers = {  
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
    'Host': 'mp.weixin.qq.com',
    'Connection': 'keep-alive',
    # 'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7',
    'Cache-Control': 'max-age=0',
    'Upgrade-Insecure-Requests': ' 1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
    'Cookie': '',
}


def __save_es(item, prefix):  
    if 'app_msg_ext_info' not in item:
        return
    comm = item['comm_msg_info']
    info = item['app_msg_ext_info']
    title = info['title']
    content_url = info['content_url']
    content_url = content_url.replace('\/', '/')
    if len(content_url.strip()) == 0:
        return
    try:
        page = request.urlopen(content_url)
    except Exception as e:
        print("访问微信链接出错了,错误原因" + e)
        return
    content = page.read().decode("utf-8")
    __post_es(prefix + ' ' + title, content, comm['datetime'])


'''  
推送文章数据给搜索引擎
'''


def __post_es(name, content, datetime):  
    h = {'Accept-Charset': 'utf-8', 'Content-Type': 'application/json'}
    params = {
        "name": name,
        "content": content,
        "datetime": datetime
    }
    resp = requests.post(es_url + index, headers=h, data=json.dumps(params))
    print(resp.content)


def reptile(url, prefix):  
    r = request.Request(url=url, headers=headers, method="GET")
    response = opener.open(r)
    offset = url[url.index('offset='):]
    offset = int(offset[7:offset.index('&')])
    htmlcode = response.read().decode()
    j = json.loads(htmlcode)
    if j['ret'] != 0:
        print('返回数据错误,请检查链接')
        exit(0)
    next_offset = j['next_offset']
    if offset == next_offset:
        return
    general_msg_list = j['general_msg_list']
    general_msg_list = json.loads(general_msg_list)
    for item in general_msg_list['list']:
        __save_es(item, prefix)
    #非常重要,为了防止被封,每次抓取数据需要休息15秒
    time.sleep(15)
    reptile(url.replace("offset=" + str(offset), 'offset=' + str(next_offset)), prefix)


# 使用抓包工具获取的链接地址
url = 'https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz=123==&f=json&offset=0&count=10&is_ok=1&scene=124&uin=123&pass_ticket=123&wxtoken=&appmsg_token=123&x5=0&f=json'  
# 为了方便搜索引擎搜索到公众号文章,可以给标题加个前缀,比如使用公众号名称
prefix = 'shufang'

reptile(url, prefix)

我反复试了网上各种方法,都可能已经过时,或者无法使用,我这个办法主要的思路是登陆PC端的微信,然后使用抓包工具,通过获取公众号历史文章记录的接口解析出文章链接。

抓包工具使用Fidder,未避免偏题,这里直接链接一篇Fidder的教程,以供参考,基本上我们只需要使用到很少的功能,获取到链接地址就行了。 Fidder教程

本文抓取的数据直接写入ElasticSearch搜索引擎中,要修改数据存储方式也比较简单,ElasticSearch怎么用这边就不再罗嗦,感兴趣的同学可以自己去了解。

主要说明一下如何获取历史文章记录的链接地址: 1、首先登陆PC版的微信
2、打开订阅号,或者服务号,点击右上角的“...”
image.png 3、点击查看历史记录
微信图片_20190923164359.png

4、打开历史记录后,滚动条往下滑动,直到加载出更多的历史文章

5、然后在Fiddler中找到如下地址的访问记录:

https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz=123==&f=json&offset=0&count=10&is_ok=1&scene=124&uin=123&pass_ticket=123&wxtoken=&appmsg_token=123&x5=0&f=json  

注意其中有个参数action=getmsg,这个是接口获取json格式返回数据,还有一条action=home的那个是获取公众号主页页面,这边我们直接用action=getmsg的接口就行了,返回数据是json格式的,并且支持分页返回,参数中的offset=12,就是分页参数,这边我们拿到地址后将地址复制到代码中的url参数,也就是代码第82行,覆盖掉原来的url='xxxxxxxxxxxxxxxxx'就可以开始爬取公众号数据了。

代码中每次抓取分页数据的时候让程序休息了15秒,主要是为了防止被微信封号,封号后可能会导致当前设备24小时内都无法获取任何公众号历史记录,切记切记!!!

有兴趣获取完整代码的同学也可以访问我的github下载:爬取公众号文章和利用ElasticSearch搜索的功能演示

代码包括爬虫爬取数据写入ElasticSearch,以及通过ElasticSearch进行文章标题和内容的搜索DEMO演示,有任何问题也欢迎私信我,大家一起探讨