搜狗微信搜索提供兩種類型的關鍵詞搜索,一種是搜索公衆號文章內容,另外一種是直接搜索微信公衆號。經過微信公衆號搜索能夠獲取公衆號的基本信息及最近發佈的10條文章,以前寫過一篇《Python 抓取微信公衆號文章》,今天來抓取一下微信公衆號的帳號信息(→ 先看結果(2998條) ←)。html
首先經過首頁進入,能夠按照類別抓取,經過「查看更多」能夠找出頁面連接規則:git
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複製代碼
上面代碼經過加載更多頁面獲取加載列表,進而從其中抓取微信公衆號詳情頁面:github
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複製代碼
進入詳情頁面能夠獲取公衆號的名稱/ID/功能介紹/帳號主體/頭像/二維碼/最近10篇文章
等信息:redis
詳情頁面連接:
http://mp.weixin.qq.com/profile?src=3×tamp=1477208282&ver=1&signature=8rYJ4QV2w5FXSOy6vGn37sUdcSLa8uoyHv3Ft7CrhZhB4wO-bbWG94aUCNexyB7lqRNSazua-2MROwkV835ilg==
sql
訪問詳情頁面時有可能須要驗證碼,自動識別驗證碼仍是頗有難度的,所以要作好爬蟲的假裝工做。flask
詳情頁面的連接中有兩個重要參數:timestamp & signature
,這說明頁面連接是有時效性的,因此保存下來應該也沒用;微信
二維碼圖片連接一樣具備時效性,所以如須要最好將圖片下載下來。app
最近 Python 社區出現了一款異步加強版的 Flask 框架:Sanic,基於uvloop和httptools,能夠達到異步、更快的效果,但保持了與 Flask 一致的簡潔語法。雖然項目剛起步,還有不少基本功能爲實現,但已經得到了不少關注(2,222 Star)。此次本打算用抓取的微信公衆號信息基於 Sanic 作一個簡單的交互應用,但無奈目前尚未加入模板功能,異步的 redis 驅動也還有 BUG 沒解決,因此簡單嘗試了一下以後仍是切換回 Flask + SQLite,先把抓取結果呈現出來,後續有機會再作更新。框架
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)複製代碼
【查看原文】異步