-
當前位置:首頁 > 創(chuàng)意學院 > 短視頻 > 專題列表 > 正文
通過爬取第三方的公眾號文章聚合網(wǎng)站
通過微信公眾平臺引用文章接口
通過抓包程序,分析微信app訪問公眾號文章的接口
import re
import time
import random
import traceback
import requests
from selenium import webdriver
class Spider(object):
'''
微信公眾號文章爬蟲
'''
def __init__(self):
# 微信公眾號賬號
self.account = '286394973@qq.com'
# 微信公眾號密碼
self.pwd = 'lei4649861'
def create_driver(self):
'''
初始化 webdriver
'''
options = webdriver.ChromeOptions()
# 禁用gpu加速,防止出一些未知bug
options.add_argument('--disable-gpu')
# 這里我用 chromedriver 作為 webdriver
# 可以去 http://chromedriver.chromium.org/downloads 下載你的chrome對應版本
self.driver = webdriver.Chrome(executable_path='./chromedriver', chrome_options=options)
# 設(shè)置一個隱性等待 5s
self.driver.implicitly_wait(5)
def log(self, msg):
'''
格式化打印
'''
print('------ %s ------' % msg)
def login(self):
'''
登錄拿 cookies
'''
try:
self.create_driver()
# 訪問微信公眾平臺
self.driver.get('https://mp.weixin.qq.com/')
# 等待網(wǎng)頁加載完畢
time.sleep(3)
# 輸入賬號
self.driver.find_element_by_xpath("./*//input[@name='account']").clear()
self.driver.find_element_by_xpath("./*//input[@name='account']").send_keys(self.account)
# 輸入密碼
self.driver.find_element_by_xpath("./*//input[@name='password']").clear()
self.driver.find_element_by_xpath("./*//input[@name='password']").send_keys(self.pwd)
# 點擊登錄
self.driver.find_elements_by_class_name('btn_login')[0].click()
self.log("請拿手機掃碼二維碼登錄公眾號")
# 等待手機掃描
time.sleep(10)
self.log("登錄成功")
# 獲取cookies 然后保存到變量上,后面要用
self.cookies = dict([[x['name'], x['value']] for x in self.driver.get_cookies()])
except Exception as e:
traceback.print_exc()
finally:
# 退出 chorme
self.driver.quit()
def get_article(self, query=''):
try:
url = 'https://mp.weixin.qq.com'
# 設(shè)置headers
headers = {
"HOST": "mp.weixin.qq.com",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36"
}
# 登錄之后的微信公眾號首頁url變化為:https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token=1849751598,
# 從這里獲取token信息
response = requests.get(url=url, cookies=self.cookies)
token = re.findall(r'token=(d+)', str(response.url))[0]
time.sleep(2)
self.log('正在查詢[ %s ]相關(guān)公眾號' % query)
search_url = 'https://mp.weixin.qq.com/cgi-bin/searchbiz?'
# 搜索微信公眾號接口需要傳入的參數(shù),
# 有三個變量:微信公眾號token、隨機數(shù)random、搜索的微信公眾號名字
params = {
'action': 'search_biz',
'token': token,
'random': random.random(),
'query': query,
'lang': 'zh_CN',
'f': 'json',
'ajax': '1',
'begin': '0',
'count': '5'
}
# 打開搜索微信公眾號接口地址,需要傳入相關(guān)參數(shù)信息如:cookies、params、headers
response = requests.get(search_url, cookies=self.cookies, headers=headers, params=params)
time.sleep(2)
# 取搜索結(jié)果中的第一個公眾號
lists = response.json().get('list')[0]
# 獲取這個公眾號的fakeid,后面爬取公眾號文章需要此字段
fakeid = lists.get('fakeid')
nickname = lists.get('nickname')
# 微信公眾號文章接口地址
search_url = 'https://mp.weixin.qq.com/cgi-bin/appmsg?'
# 搜索文章需要傳入幾個參數(shù):登錄的公眾號token、要爬取文章的公眾號fakeid、隨機數(shù)random
params = {
'action': 'list_ex',
'token': token,
'random': random.random(),
'fakeid': fakeid,
'lang': 'zh_CN',
'f': 'json',
'ajax': '1',
'begin': '0', # 不同頁,此參數(shù)變化,變化規(guī)則為每頁加5
'count': '5',
'query': '',
'type': '9'
}
self.log('正在查詢公眾號[ %s ]相關(guān)文章' % nickname)
# 打開搜索的微信公眾號文章列表頁
response = requests.get(search_url, cookies=self.cookies, headers=headers, params=params)
time.sleep(2)
for per in response.json().get('app_msg_list', []):
print('title ---> %s' % per.get('title'))
print('link ---> %s' % per.get('link'))
# print('cover ---> %s' % per.get('cover'))
except Exception as e:
traceback.print_exc()
if __name__ == '__main__':
spider = Spider()
spider.login()
spider.get_article('python')
抓取微信APP登錄數(shù)據(jù)
大家好!今天讓創(chuàng)意嶺的小編來大家介紹下關(guān)于抓取微信APP登錄數(shù)據(jù)的問題,以下是小編對此問題的歸納整理,讓我們一起來看看吧。
本文目錄:
一、如何抓取微信所有公眾號最新文章
經(jīng)常有朋友需要幫忙做公眾號文章爬取,這次來做一個各種方法的匯總說明。
目前爬取微信公眾號的方法主要有3種:
通過第三方的公眾號文章聚合網(wǎng)站爬取
微信公眾號文章一直沒有提供一個對外的搜索功能,直到2013年微信投資搜狗之后,搜狗搜索接入微信公眾號數(shù)據(jù),從此使用搜狗搜索就可以瀏覽或查詢到相關(guān)公眾號以及文章。
域名是: https://weixin.sogou.com/
可以直接搜索公眾號或者文章的關(guān)鍵字,一些熱門的公眾號更新還是很及時的,幾乎做到了和微信同步。
所以,爬一些熱門公眾號可以使用搜狗微信的接口來做,但是一些小眾公眾號是搜索不到的,而且搜狗的防爬機制更新的比較勤,獲取數(shù)據(jù)的接口變化的比較快,經(jīng)常兩三個月就有調(diào)整,導致爬蟲很容易掛,這里還是建議使用 selenium爬比較省心。另外搜狗對每個ip也有訪問限制,訪問太頻ip會被封禁24小時,需要買個ip池來做應對。
還有一些其他公眾號文章聚合網(wǎng)站(比如傳送門)也都存在更新不及時或者沒有收錄的問題,畢竟搜狗這個親兒子都不行。
通過微信公眾平臺引用文章接口
這個接口比較隱蔽而且沒法匿名訪問,所有得有一個公眾號,建議新注冊一個公眾號比較好,免得被封。
下面開始具體步驟:首先登錄自己的微信公眾號,在進去的首頁選擇 新建群發(fā),然后再點擊 自建圖文,在文章編輯工具欄中找到 超鏈接,如下圖:
點擊這個超鏈接按鈕,就會彈出一個對話框,鏈接輸入方式這一項選中 查找文章,如下圖:
到這里就可以輸入公眾號的名字,回車之后微信就會返回相匹配的公眾號列表,接著點擊你想抓取的公眾號,就會顯示具體的文章列表了,已經(jīng)是按時間倒序了,最新的文章就是第一條了。
微信的分頁機制比較奇怪,每個公眾號的每頁顯示的數(shù)據(jù)條數(shù)是不一樣的,分頁爬的時候要處理一下。
通過chrome分析網(wǎng)絡(luò)請求的數(shù)據(jù),我們想要的數(shù)據(jù)已經(jīng)基本拿到了,文章鏈接、封面、發(fā)布日期、副標題等,如
由于微信公眾平臺登錄驗證比較嚴格,輸入密碼之后還必須要手機掃碼確認才能登錄進去,所以最好還是使用 selenium做自動化比較好。具體微信接口的分析過程我就不列了,直接貼代碼了:
代碼只是作為學習使用,沒有做分頁查詢之類。實測過接口存在訪問頻次限制,一天幾百次還是沒啥問題,太快或者太多次訪問就會被封24小時。
二、xposed + python 怎么爬取微信朋友圈的數(shù)據(jù)
有JAVA的,你參考一下
主要思路
從UI獲取文本信息是最為簡單的方法,于是應該優(yōu)先逆向UI代碼部分。
逆向微信apk
首先解包微信apk,用dex2jar反編譯classes.dex,然后用JD-GUI查看jar源碼。當然,能看到的源碼都是經(jīng)過高度混淆的。但是,繼承自安卓重要組件(如Activity、Service等)的類名無法被混淆,于是還是能從中看到點東西。
首先定位到微信APP package。我們知道這個是 com.tencent.mm
。
在 com.tencent.mm
中,我們找到一個 ui
包,有點意思。
展開 com.tencent.mm.ui
,發(fā)現(xiàn)多個未被混淆的類,其中發(fā)現(xiàn) MMBaseActivity
直接繼承自 Activity
, MMFragmentActivity
繼承自 ActionBarActivity
, MMActivity
繼承自 MMFragmentActivity
,并且 MMActivity
是微信中大多數(shù)Activity的父類:
public class MMFragmentActivity
extends ActionBarActivity
implements SwipeBackLayout.a, b.a {
...
}
public abstract class MMActivity
extends MMFragmentActivity {
...
}
public class MMBaseActivity
extends Activity {
...
}
現(xiàn)在需要找出朋友圈的Activity,為此要用Xposed hook MMActivity
。
創(chuàng)建一個Xposed模塊
參考 [TUTORIAL]Xposed module devlopment
,創(chuàng)建一個Xposed項目。
簡單Xposed模塊的基本思想是:hook某個APP中的某個方法,從而達到讀寫數(shù)據(jù)的目的。
小編嘗試hook com.tencent.mm.ui.MMActivity.setContentView
這個方法,并打印出這個Activity下的全部TextView內(nèi)容。那么首先需要遍歷這個Activity下的所有TextView,遍歷ViewGroup的方法參考了SO的以下代碼:
private void getAllTextViews(final View v) {
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {
View child = vg.getChildAt(i);
getAllTextViews(child);
}
} else if (v instanceof TextView ) {
dealWithTextView((TextView)v); //dealWithTextView(TextView tv)方法:打印TextView中的顯示文本
}
}
Hook MMActivity.setContentView
的關(guān)鍵代碼如下:
findAndHookMethod("com.tencent.mm.ui.MMActivity", lpparam.classLoader, "setContentView", View.class, new XC_MethodHook() {
...
});
在findAndHookMethod方法中,第一個參數(shù)為完整類名,第三個參數(shù)為需要hook的方法名,其后若干個參數(shù)分別對應該方法的各形參類型。在這里, Activity.setContentView(View view)
方法只有一個類型為 View
的形參,因此傳入一個 View.class
。
現(xiàn)在,期望的結(jié)果是運行時可以從Log中讀取到每個Activity中的所有的TextView的顯示內(nèi)容。
但是,因為View中的數(shù)據(jù)并不一定在 setContentView()
時就加載完畢,因此小編的實驗結(jié)果是,log中啥都沒有。
意外的收獲
當切換到朋友圈頁面時,Xposed模塊報了一個異常,異常源從 com.tencent.mm.plugin.sns.ui.SnsTimeLineUI
這個類捕捉到。從類名上看,這個很有可能是朋友圈首頁的UI類。展開這個類,發(fā)現(xiàn)更多有趣的東西:
這個類下有個子類 a
(被混淆過的類名),該子類下有個名為 gyO
的 ListView
類的實例。我們知道, ListView
是顯示列表類的UI組件,有可能就是用來展示朋友圈的列表。
順藤摸瓜
那么,我們先要獲得一個 SnsTimeLineUI.a.gyO
的實例。但是在這之前,要先獲得一個 com.tencent.mm.plugin.sns.ui.SnsTimeLineUI.a
的實例。繼續(xù)搜索,發(fā)現(xiàn) com.tencent.mm.plugin.sns.ui.SnsTimeLineUI
有一個名為 gLZ
的 SnsTimeLineUI.a
實例,那么我們先取得這個實例。
經(jīng)過測試, com.tencent.mm.plugin.sns.ui.SnsTimeLineUI.a(boolean, boolean, String, boolean)
這個方法在每次初始化微信界面的時候都會被調(diào)用。因此我們將hook這個方法,并從中取得 gLZ
。
findAndHookMethod("com.tencent.mm.plugin.sns.ui.SnsTimeLineUI", lpparam.classLoader, "a", boolean.class, boolean.class, String.class, boolean.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Hooked. ");
Object currentObject = param.thisObject;
for (Field field : currentObject.getClass().getDeclaredFields()) { //遍歷類成員
field.setAccessible(true);
Object value = field.get(currentObject);
if (field.getName().equals("gLZ")) {
XposedBridge.log("Child A found.");
childA = value;
//這里獲得了gLZ
...
}
}
}
});
現(xiàn)在取得了 SnsTimeLineUI.a
的一個實例 gLZ
,需要取得這個類下的 ListView
類型的 gyO
屬性。
private void dealWithA() throws Throwable{
if (childA == null) {
return;
}
for (Field field : childA.getClass().getDeclaredFields()) { //遍歷屬性
field.setAccessible(true);
Object value = field.get(childA);
if (field.getName().equals("gyO")) { //取得了gyO
ViewGroup vg = (ListView)value;
for (int i = 0; i < vg.getChildCount(); i++) { //遍歷這個ListView的每一個子View
...
View child = vg.getChildAt(i);
getAllTextViews(child); //這里調(diào)用上文的getAllTextViews()方法,每一個子View里的所有TextView的文本
...
}
}
}
}
現(xiàn)在已經(jīng)可以將朋友圈頁面中的全部文字信息打印出來了。我們需要根據(jù)TextView的子類名判斷這些文字是朋友圈內(nèi)容、好友昵稱、點贊或評論等。
private void dealWithTextView(TextView v) {
String className = v.getClass().getName();
String text = ((TextView)v).getText().toString().trim().replaceAll("\n", " ");
if (!v.isShown())
return;
if (text.equals(""))
return;
if (className.equals("com.tencent.mm.plugin.sns.ui.AsyncTextView")) {
//好友昵稱
...
}
else if (className.equals("com.tencent.mm.plugin.sns.ui.SnsTextView")) {
//朋友圈文字內(nèi)容
...
}
else if (className.equals("com.tencent.mm.plugin.sns.ui.MaskTextView")) {
if (!text.contains(":")) {
//點贊
...
} else {
//評論
...
}
}
}
自此,我們已經(jīng)從微信APP里取得了朋友圈數(shù)據(jù)。當然,這部分抓取代碼需要定時執(zhí)行。因為從 ListView
中抓到的數(shù)據(jù)只有當前顯示在屏幕上的可見部分,為此需要每隔很短一段時間再次執(zhí)行,讓用戶在下滑加載的過程中抓取更多數(shù)據(jù)。
剩下的就是數(shù)據(jù)分類處理和格式化輸出到文件,受本文篇幅所限不再贅述,詳細實現(xiàn)可參考作者GitHub上的源碼。
三、怎樣通過app查看微信被誰登錄過
微信里面有訂閱號、可以自己查看。
四、微信聊天記錄如何提取出來
微信聊天記錄提取出來的具體操作如下:
工具:華為手機。微信APP。
1、打開手機,登錄微信主頁面,點擊右下角的“我”。
2、點擊界面中的【設(shè)置】選項卡。
3、在【設(shè)置】界面中,選擇【聊天】選項卡。
4、在接下來彈出的界面中,選擇【聊天記錄備份與遷移】選項卡,然后就可以導出微信聊天記錄了。
以上就是關(guān)于抓取微信APP登錄數(shù)據(jù)相關(guān)問題的回答。希望能幫到你,如有更多相關(guān)問題,您也可以聯(lián)系我們的客服進行咨詢,客服也會為您講解更多精彩的知識和內(nèi)容。
推薦閱讀:
抓取百度關(guān)鍵詞電話(抓取百度關(guān)鍵詞電話的方法)
轉(zhuǎn)mbr后無法進入系統(tǒng)(mbr轉(zhuǎn)guid后無法啟動)