专栏首页WeaponZhi使用Python快速获取公众号文章定制电子书(一)

使用Python快速获取公众号文章定制电子书(一)

阅读本篇大概需要 11 分钟。

一年有这么多情人节,什么时候,你可以为她唱 a song for love

因为工作原因,小之停更了一段时间,发生了很多事,不过从今天开始,我将会满血复活。这篇文章将分享一个我最近写的 Python 相关的小 demo 。爬取某个公众号的所有历史文章,并导出到本地,方便之后在线下环境直接观看。

这个功能还是有一定实际用途的,需求和功能虽然简单明确,但我在开发的过程中,也是遇到了一定的问题,可以说好好的把 Python 爬虫方面的知识复习了一遍。我也将从最基础的抓包开始讲起,希望能提供一个完整爬取流程的简单教程。

抓包

在 Windows 平台,我们经常使用 Fiddler 来进行抓包,笔者使用 Mac,所以比较习惯使用 Charles 来进行抓包。不仅如此,这类工具在开发过程中是非常重要的工具,笔者平时在客户端开发过程中,如果服务端接口还没完成,只要定义好数据结构,通过这类工具的重定向功能,就可以轻易的自己模拟数据来开发了。

用手机抓取 https 接口,需要在手机里安装证书,网上方法很多,我这里就不费篇幅了。

我们打开微信历史消息界面,然后在 Charles 里面找寻接口,通过观察 Response 返回的内容,我们发现了我们需要的请求:

第一页爬取

我们在 Python 中记录下这个 url 和 Header,需要注意的是,这个url请求的数据只是第一页的数据,上拉加载的url接口形式是完全不同的。

url = ".."

headers = """
Host: mp.weixin.qq.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Linux; Android 6.0.1; NX531J Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044030 Mobile Safari/537.36 MicroMessenger/6.6.5.1280(0x26060532) NetType/WIFI Language/zh_CN
x-wechat-key: b97b0a94956e0cb26093b03bcbfb059796e335db8c12a8036cdff0191103874cee2a5045062b4058d71c848ab74c8b256570c9a9547fe2eb9572b1a762f9cea43f91428b4a31bf5618a8c61c00da7287
x-wechat-uin: MTMzNjE3ODYyMQ%3D%3D
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,image/wxpic,image/sharpp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en-US;q=0.8
Cookie: sd_userid=96301522585723838; sd_cookie_crttime=1522585723838; pgv_pvid=1151171120; tvfe_boss_uuid=92a513a6354c3896; rewardsn=; wxtokenkey=777; wxuin=1336178621; devicetype=android-23; version=26060532; lang=zh_CN; pass_ticket=Pu/H3aPR7f/zgA52T+v4fU9wSWkY5tgGGgAXWewji2dqpMDrjaxUbBR/mo2e/aMX; wap_sid2=CL3vkf0EEnBSWHFYWmVoZVpOMjU0cnBpSUhiLWF2cmZHVVVLVWZrWUp4QVRlclVVOTRwS1hmMGNUR0VJaXp1RlVzbGViM2wtZnVfakZVd21RcGxxbzI3U3R3cmtYYlUycXpLU0FzcGJFSm1ESkZsYVhzSzhBd0FBMLbQ5dcFOA1AlU4=
Q-UA2: QV=3&PL=ADR&PR=WX&PP=com.tencent.mm&PPVN=6.6.5&TBSVC=43603&CO=BK&COVC=044030&PB=GE&VE=GA&DE=PHONE&CHID=0&LCID=9422&MO= NX531J &RL=1080*1920&OS=6.0.1&API=23
Q-GUID: 6a875f18ea5ba76bb6afb9ca13b788cb
Q-Auth: 31045b957cf33acf31e40be2f3e71c5217597676a9729f1b
"""

这个请求返回的是一个 H5 界面,并不是我们期望的是一个 JSON 文件,但没关系,通过我们的 xml 解析器,我们始终可以通过细致的观察,找寻我们需要的信息。我们发现,下面这段代码,隐藏着前十条文章的数据列表。

def extract_data(html_content):
    rex = "msgList = '({.*?})'"
    pattern = re.compile(pattern=rex, flags=re.S)
    match = pattern.search(html_content)
    if match:
        data = match.group(1)
        data = html.unescape(data)
        data = json.loads(data)
        articles = data.get("list")
        articles_lists = dict()
        for item in articles:
            if item.get("app_msg_ext_info"):
                articles_lists[item["app_msg_ext_info"]["title"]] = item["app_msg_ext_info"]["content_url"]
        return articles_lists

我们可以通过正则来提取出这部分数据,保存在 json 中,现在让我们来分析下数据:

article = {'app_msg_ext_info': 
                {'title': '那些对印度的误解与偏见',
                 'copyright_stat': 11,
                 'is_multi': 1,
                 'content': '',
                 'author': 'WeaponZhi',
                 'subtype': 9,
                 'del_flag': 1,
                 'fileid': 502883895,
                 'content_url': 'http:\\/\\/mp....',
                 ''
                 'digest': '提到印度,你首先会想到什么',
                 'cover': 'http:\\/\\/mmbiz.qpic.cn\\...',
                 'multi_app_msg_item_list': [{'fileid': 861719336,
                                              'content_url': 'http:\\/\\/mp...',
                                              'content': '', 'copyright_stat': 11,
                                              'cover': 'http:\\/\\/mmbiz.qpic.cn',
                                              'del_flag': 1,
                                              'digest': '携程再努努力就快赶上百度了',
                                              '...

根据我们历史文章的样式,以及我们需要的数据和需求,笔者抽取了每篇文章的几个重要字段:

title:文章标题

content_url:文章链接

digest:摘要

multi_app_msg_item_list:同时发送的其他文章的字段列表

multi_app_msg_item_list 字段就是一组多图文数据列表,在微信里的展现形式是这样的

现在我们拿到了每篇文章的具体链接 content_url,后面我们需要做的就是请求这个url,从中抽取文章内容,再把内容以一定的格式保存在文件中即可。

headers = headers_to_dict(headers)
response = requests.get(url, headers=headers, verify=False)
if '<title>验证</title>' in response.text:
    raise Exception("获取微信公众号文章失败,可能是因为你的请求参数有误,请重新获取")
data = extract_data(response.text)
rex = r'\\/'
for item in data:
    pattern = re.sub(rex, '/', html.unescape(data.get(item)))
    response = requests.get(pattern, headers=headers, verify=False)
    parser_text_to_file(item, response.text)

def parser_text_to_file(title, article_content):
    soup = BeautifulSoup(article_content, 'html.parser', from_encoding='utf8')
    node = soup.find(id="js_content")
    write_text_to_file(title, node)


def write_text_to_file(title, node):
    contents = node.descendants
    for item in contents:
        if isinstance(item, NavigableString):
            with open(title, "a", encoding="utf-8") as f:
                f.write(str(item))
                f.write('\n\n')

这里我们写了一个验证判断,为了防止过度的爬取操作,爬取历史文章的接口 Cookie 只能有一定的有效时间,如果你在爬取过程中发现获取数据失败,那你就需要重新进入界面然后更新代码中的 Header 中的Cookie了,我们在后面的文章中对这个问题将进行具体解析。

实际上上面的代码就是这个小 demo 的业务核心了,我们现在只处理了历史文章前十篇的内容,下篇文章我将通过加载更多接口,将一个公众号所有文章爬取出来,更有意思的自然还在后面。

本文分享自微信公众号 - AI极客研修站(WeaponZhi)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-05-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python爬虫实践——简单爬取我的博客

    学任何一门技术,如果没有实践,技术就难以真正的吸收。利用上次博客讲解的三个知识点:URL 管理器、网页下载器和网页解析器来爬取一下我的博客。 我的博客地址 ht...

    小之丶
  • 机器学习股票价格预测初级实战

    上一篇文章,我用了4000字这样比较长的篇幅,介绍了一些金融和量化交易相关的基本知识,还大概说了下人工智能在金融方面使用的优劣。这篇文章我们将用一个具体代码来进...

    小之丶
  • 使用Python快速获取公众号文章定制电子书(二)

    接上篇文章使用Python快速获取公众号文章定制电子书(一)。我们现在已经成功的将公众号历史消息的前十条文章给爬取了出来,使用 content_url 这个关键...

    小之丶
  • Python+selenium 自动化-获取当前页面的url地址,打开指定的url地址

    非常简单,driver.current_url 就能获取当前页面的 url 地址。

    小蓝枣
  • dotnet使用Selenium执行自动化任务

    源码地址:https://coding.net/u/yimocoding/p/WeDemo/git/tree/SeleniumDemo/SeleniumDemo

    易墨
  • python爬虫入门实战(三)不会正则怎么办?xpath分分钟搞定!

    在 python爬虫入门实战!爬取博客文章标题和链接!和 python爬虫入门实战(二)!多线程爬虫! 我们已经学了一些基本技巧。但是之前都是用正则表达式来解析...

    白玉无冰
  • python+Selenium自动化测试——输入,点击操作

    打开百度首页,搜索“胡歌”,然后检索列表,有无“胡歌的新浪微博”这个链接 2、在写脚本之前,需要明确测试的步骤,具体到每个步骤需要做什么,既拆分测试场景,考虑好...

    砸漏
  • entity framework使用技巧

    1、无需先查询数据的修改方法 // 将创建的data实体添加到ObjectContext db.Data.Attach(data); // 手动设置状态为修改 ...

    Java中文社群_老王
  • selenium切换窗口后定位元素出现问题的解决方案

    在做UI自动化的过程中,有时需要由一个窗口跳转到另一个窗口,这时直接去定位页面元素,可能会出现问题,这时,我们需要将driver与新的窗口进行绑定。

    流柯
  • Mac OS环境配置chromedriver

    selenium之 chromedriver与chrome版本映射表(更新至v2.29)

    freesan44

扫码关注云+社区

领取腾讯云代金券