Python 抓取微信公众号账号信息
prhs7545
8年前
<p>搜狗微信搜索提供两种类型的关键词搜索,一种是搜索公众号文章内容,另一种是直接搜索微信公众号。通过微信公众号搜索可以获取公众号的基本信息及最近发布的10条文章,之前写过一篇《 <a href="http://www.open-open.com/lib/view/open1477810960467.html" rel="nofollow,noindex">Python 抓取微信公众号文章</a> 》,今天来抓取一下微信公众号的账号信息( 先看结果(2998条) :查看原文 )。</p> <p><img src="https://simg.open-open.com/show/78ab5c7874cd70558695488d06accc49.jpg"> 爬虫</p> <p>首先通过首页进入,可以按照类别抓取,通过“查看更多”可以找出页面链接规则:</p> <p><img src="https://simg.open-open.com/show/a99dcab665057fe3db8be7948ea91974.jpg"></p> <pre> <code class="language-python">import requests as req import re reTypes = r'id="pc_\d*" uigs="(pc_\d*)">([\s\S]*?)</a>' Entry = "http://weixin.sogou.com/" entryPage = req.get(Entry) allTypes = re.findall(reTypes, getUTF8(entryPage)) for (pcid, category) in allTypes: for page in range(1, 100): url = 'http://weixin.sogou.com/pcindex/pc/{}/{}.html'.format(pcid, page) print(url) categoryList = req.get(url) if categoryList.status_code != 200: break</code></pre> <p>上面代码通过加载更多页面获取加载列表,进而从其中抓取微信公众号详情页面:</p> <pre> <code class="language-python">reProfile = r'<li id[\s\S]*?<a href="([\s\S]*?)"' allProfiles = re.findall(reOAProfile, getUTF8(categoryList)) for profile in allProfiles: profilePage = req.get(profile) if profilePage.status_code != 200: continue</code></pre> <p>进入详情页面可以获取公众号的 名称/ID/功能介绍/账号主体/头像/二维码/最近10篇文章 等信息:</p> <p><img src="https://simg.open-open.com/show/4b84a95a0cff38a544a3c7bf92bb489a.jpg"></p> <p>1. 验证码</p> <p>访问详情页面时有可能需要验证码,自动识别验证码还是很有难度的,因此要做好爬虫的伪装工作。</p> <p>2. 未保存详情页面链接</p> <p>详情页面的链接中有两个重要参数: timestamp & signature ,这说明页面链接是有时效性的,所以保存下来应该也没用;</p> <p>3. 二维码</p> <p>二维码图片链接同样具有时效性,因此如需要最好将图片下载下来。</p> <h3>用 Flask 展示结果</h3> <p>最近 Python 社区出现了一款异步增强版的 Flask 框架: Sanic ,基于 uvloop 和 httptools ,可以达到异步、更快的效果,但保持了与 Flask 一致的简洁语法。虽然项目刚起步,还有很多基本功能为实现,但已经获得了很多关注( 2,222 Star )。这次本打算用抓取的微信公众号信息基于 Sanic 做一个简单的交互应用,但无奈目前还没有加入模板功能,异步的 redis 驱动也还有 BUG 没解决,所以简单尝试了一下之后还是切换回 Flask + SQLite,先把抓取结果呈现出来,后续有机会再做更新。</p> <p>安装 Sanic</p> <p><img src="https://simg.open-open.com/show/56cc6f41dd51e043826d279e1b5efa23.jpg"> Debug Sanic</p> <p><img src="https://simg.open-open.com/show/bd1040d12d824ce526c18d99f1a9b32a.png"> Flask + SQLite App</p> <pre> <code class="language-python">from flask import g, Flask, render_template import sqlite3 app = Flask(__name__) DATABASE = "./db/wx.db" def get_db(): db = getattr(g, '_database', None) if db is None: db = g._database = sqlite3.connect(DATABASE) return db @app.teardown_appcontext def close_connection(exception): db = getattr(g, '_database', None) if db is not None: db.close() @app.route("/<int:page>") @app.route("/") def hello(page=0): cur = get_db().cursor() cur.execute("SELECT * FROM wxoa LIMIT 30 OFFSET ?", (page*30, )) rows = [] for row in cur.fetchall(): rows.append(row) return render_template("app.html", wx=rows, cp=page) if __name__ == "__main__": app.run(debug=True, port=8000)</code></pre> <p> </p> <p>来自:http://mp.weixin.qq.com/s?__biz=MzI0NjIxMzE5OQ==&mid=2656697912&idx=1&sn=7c43d3c59b265650dd58c25bed18d304&chksm=f2efe118c598680e40393961af060bd1358f9d29b2bc5050cb2e0ca2ce5d9f93eaabea6fcb8a#rd</p> <p> </p>