微信公眾號文章爬蟲

很多的微信公眾號都提供了質量比較高的文章閱讀,對于自己喜歡的微信公眾號,所以想做個微信公眾號爬蟲,爬取相關公眾號的所有文章。抓取公眾號的所有的文章,需要獲取兩個比較重要的參數。一個是微信公眾號的唯一ID(__biz)和獲取單一公眾號的文章權限值wap_sid2。接下來說一下思路。

  • 爬取思路:
    • 要想獲取微信公眾號的爬蟲,首先要唯一標識這個微信公眾號,所以要獲取這個微信公眾號的id值(即__biz)。看了比較多的相關文章,很多獲取__biz的值比較機械,單純手動復制取__biz;現在搜狗引擎與微信公眾號對接,為我們提供了一個很好的獲取途徑,微信公眾號源碼里面有該號的__biz值(可以從這個途徑獲取);但是搜狗引擎對微信公眾號有限制,只顯示最近10條文章,所以我們單純只從搜狗引擎獲取__biz值和通過搜狗搜索任意關鍵詞公眾號列表。
    • 下面是搜狗搜索微信公眾號的URL地址,其中query的python是搜索的關鍵詞,其他可以不變。
    http://weixin.sogou.com/weixin?type=1&s_from=input&query=python&ie=utf8&_sug_=n&_sug_type_=
    
    • 下面是搜索的結果頁面:
搜索結果
  • 查看源代碼,可以發現每一個公眾號的鏈接,都是位于id為sougou_vr_11002301_box_n(n為整數如1,2,3等)下面的a標簽href屬性值。通過xpath語法可以獲取,其中n的位置可以按規律順序獲取:
//*[@id="sogou_vr_11002301_box_n"]/div/div[2]/p[1]/a
  • 獲取到單個公眾號的地址如下所示:
http://mp.weixin.qq.com/profile?src=3&timestamp=1508003829&ver=1&signature=Eu9LOYSA47p6WE0mojhMtFR-gSr7zsQOYo6*w5VxrUgy7RbCsdkuzfFQ1RiSgM3i9buMZPrYzmOne6mJxCtW*g==
  • 打開單個公眾號鏈接,獲取公眾號源碼,取其中微信公眾號的id值:
只有10條文章達不到要求
 //其中biz值就是微信公眾號的唯一id值。前面和后面省略了大部分代碼;該段代碼位于script標簽里面;該代碼還有最近10條文章的數據,如果單純想獲取最近10條,可以通過正則表達式來直接獲取
  var biz = "MzIwNDA1OTM4NQ==" || "";
  var src = "3" ; 
  var ver = "1" ; 
  var timestamp = "1508003829" ; 
  var signature = "Eu9LOYSA47p6WE0mojhMtFR-gSr7zsQOYo6*w5VxrUgy7RbCsdkuzfFQ1RiSgM3i9buMZPrYzmOne6mJxCtW*g==" ; 
  var name="python6359"||"python";
    1. 獲取到微信公眾號的id值之后,就是要獲取wap_sid值(即單個微信公眾號的文章權限值。)這個部分從微信客戶端獲取,接下來通過Fiddler抓包工具獲取,如果不知道抓包工具的環境搭建,可以參考 fiddler抓取摩拜單車數據包
    • 獲取微信公眾號文章的權限值的url:
    GET /mp/profile_ext?action=home&__biz=MjM5MDI1ODUyMA==&scene=124&devicetype=iOS10.0.1&version=16051220&lang=zh_CN&nettype=WIFI&a8scene=3&fontScale=100&pass_ticket=ji%2B3JbA2NNExGwdNCoIa91sbgwDmSmHsdZhHP5eo%2Bgun%2By2V3lxc34GQy3W5u8mE&wx_header=1 HTTP/1.1
    
    • 相應的請求頭,其中x-wechat-key是隔段時間更換一次,所以需要定時更換一次;X-WECHAT-UIN可以不變。pass_ticket也可以一段時間內不做改變,:
         'Host':'mp.weixin.qq.com',
          # 'X-WECHAT-KEY': 'a83687cde3ca46be517cdbcba60732159f229a03507e9afa1e0dfee00e3cf00562aee022e84b9011924fdbb0c7af8c647c33b1338b11ebdc8893d5df41dd34a536e1af5b48d15c87b4aef629ad8685f3',
          'X-WECHAT-KEY': '33c1fdebcfc1d1ecd9df5003dc9d9ccb6a1f5458eb704e58a05e80c73e8793dede6b52115a74a515d4d12c9a6f2d8f00238afe17cca3635d80d661a612a4a0bf48a2547516b12030efd8a224548636d2',
          'X-WECHAT-UIN':'MTU2MzIxNjQwMQ%3D%3D',
          'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
          'User-Agent':'Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_1 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Mobile/14A403 MicroMessenger/6.5.18 NetType/WIFI Language/zh_CN',
          'Accept-Language':'zh-cn',
          'Accept-Encoding':'gzip, deflate',
          'Connection':'keep-alive',
          'Cookie':'wxuin=1563216401;pass_ticket=oQDl45NRtfvQIxv2j2pYDSOOeflIXU7V3x1TUaOTpi6SkMp2B3fJwF6TE40ATCpU;ua_id=Wz1u21T8nrdNEyNaAAAAAOcFaBcyz4SH5DoQIVDcnao=;pgv_pvid=7103943278;sd_cookie_crttime=1501115135519;sd_userid=8661501115135519;3g_guest_id=-8872936809911279616;tvfe_boss_uuid=8ed9ed1b3a838836;mobileUV=1_15c8d374ca8_da9c8;pgv_pvi=8005854208',
          'Referer':"https://mp.weixin.qq.com/mp/getmasssendmsg?__biz=MjM5MzI5MTQ1Mg==&devicetype=iOS10.0.1&version=16051220&lang=zh_CN&nettype=WIFI&ascene=3&fontScale=100&pass_ticket=oQDl45NRtfvQIxv2j2pYDSOOeflIXU7V3x1TUaOTpi6SkMp2B3fJwF6TE40ATCpU&wx_header=1"
    
    • 上面的請求url獲取的返回響應頭,是設置wap_sid2獲取單一公眾號文章的權限值,我們就是要獲取set-cookies中的wap-sid2值。:
    HTTP/1.1 200 OK
    Content-Type: text/html; charset=UTF-8
    Cache-Control: no-cache, must-revalidate
    Strict-Transport-Security: max-age=15552000
    Set-Cookie: wxuin=1563216401; Path=/; HttpOnly
    Set-Cookie: pass_ticket=ji+3JbA2NNExGwdNCoIa91sbgwDmSmHsdZhHP5eo+gun+y2V3lxc34GQy3W5u8mE; Path=/; HttpOnly
    Set-Cookie: wap_sid2=CJGUs+kFElxER01KN1ZkVElJMUdhTktDUUk2LUZHNkFwT1Rzc1EwUWpWaW5ZMHlFQi15cUo1VWFjamNLM3pjdzNCbDc2ZFZpOW0xeDdPb0czWXNuQUdmbVdyOFZiNTREQUFBfjC+7YvPBTgMQJRO; Path=/; HttpOnly
    Connection: keep-alive
    Content-Length: 37211
    
    • 獲取到公眾號id值__biz和權限值wap_sid2;我們就可以構造請求獲取文章列表了。其中mongodb操作是為了獲取公眾號id值,然后根據id值,獲取wap_sid2值,然后把id值和wap_sid2對應入庫。
    # -*- coding: utf-8 -*-
    from scrapy import Spider,Request
    from .mongo import MongoOperate
    import re
    from wechatSpider.items import GetsessionspiderItem
    from .settings import *
    class GetsessionSpider(Spider):
        name = "getSession"
        allowed_domains = ["mp.weixin.qq.com"]
        start_urls = ['https://mp.weixin.qq.com/']
        headers={
            'Host':'mp.weixin.qq.com',
            # 'X-WECHAT-KEY': 'a83687cde3ca46be517cdbcba60732159f229a03507e9afa1e0dfee00e3cf00562aee022e84b9011924fdbb0c7af8c647c33b1338b11ebdc8893d5df41dd34a536e1af5b48d15c87b4aef629ad8685f3',
            'X-WECHAT-KEY': '33c1fdebcfc1d1ecd9df5003dc9d9ccb6a1f5458eb704e58a05e80c73e8793dede6b52115a74a515d4d12c9a6f2d8f00238afe17cca3635d80d661a612a4a0bf48a2547516b12030efd8a224548636d2',
            'X-WECHAT-UIN':'MTU2MzIxNjQwMQ%3D%3D',
            'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'User-Agent':'Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_1 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Mobile/14A403 MicroMessenger/6.5.18 NetType/WIFI Language/zh_CN',
            'Accept-Language':'zh-cn',
            'Accept-Encoding':'gzip, deflate',
            'Connection':'keep-alive',
            'Cookie':'wxuin=1563216401;pass_ticket=oQDl45NRtfvQIxv2j2pYDSOOeflIXU7V3x1TUaOTpi6SkMp2B3fJwF6TE40ATCpU;ua_id=Wz1u21T8nrdNEyNaAAAAAOcFaBcyz4SH5DoQIVDcnao=;pgv_pvid=7103943278;sd_cookie_crttime=1501115135519;sd_userid=8661501115135519;3g_guest_id=-8872936809911279616;tvfe_boss_uuid=8ed9ed1b3a838836;mobileUV=1_15c8d374ca8_da9c8;pgv_pvi=8005854208',
            'Referer':"https://mp.weixin.qq.com/mp/getmasssendmsg?__biz=MjM5MzI5MTQ1Mg==&devicetype=iOS10.0.1&version=16051220&lang=zh_CN&nettype=WIFI&ascene=3&fontScale=100&pass_ticket=oQDl45NRtfvQIxv2j2pYDSOOeflIXU7V3x1TUaOTpi6SkMp2B3fJwF6TE40ATCpU&wx_header=1"
       }
      # 查看歷史消息列表,現在需要捕獲wap_sid2這個值,來獲取訪問權限
      url="https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz={biz}&scene=124&devicetype=iOS10.0.1&version=16051220&lang=zh_CN&nettype=WIFI&a8scene=3&fontScale=100&pass_ticket=oQDl45NRtfvQIxv2j2pYDSOOeflIXU7V3x1TUaOTpi6SkMp2B3fJwF6TE40ATCpU&wx_header=1"
      def start_requests(self):
          MongoObj=MongoOperate(MONGO_URI,MONGO_DATABASE,MONGO_USER,MONGO_PASS,WECHATID)
          MongoObj.connect()
          items=MongoObj.finddata()
          for item in items:
              biz=item["wechatID"]
              yield Request(url=self.url.format(biz=biz),dont_filter=True,headers=self.headers,callback=self.parse,meta={"proxy":"http://127.0.0.1:8888","biz":biz})
      def parse(self, response):
         item=GetsessionspiderItem()
         data=response.headers
         needCon=data["Set-Cookie"]
         wap=needCon.decode("utf-8")
         wap=wap.split(';')
         wap=wap[0].split('=')
         wap_sid2=wap[1]
         print(wap_sid2)
         item["biz"]=response.request.meta["biz"]
         item["wap_sid2"]=str(wap_sid2)
         yield item
         # print(item)
    
獲取的wap_sid2和__biz值
  • 在mongoDB中保存著一個公眾號的id值及對應的wap_sid2值,接下來構造請求文章的值,也是獲取公眾號文章列表url。
# -*- coding: utf-8 -*-
import scrapy
from scrapy import Request
from .mongo import MongoOperate
import json
from .settings import *
class DataSpider(scrapy.Spider):
    name = "data"
    allowed_domains = ["mp.weixin.qq.com"]
    start_urls = ['https://mp.weixin.qq.com/']
    count=10
    url="https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz={biz}&f=json&offset={index}&count=10&is_ok=1&scene=124&uin=777&key=777&pass_ticket=ULeI%2BILkTLA2IpuIDqbIla4jG6zBTm1jj75UIZCgIUAFzOX29YQeTm5UKYuXU6JY&wxtoken=&appmsg_token=925_%252B4oEmoVo6AFzfOotcwPrPnBvKbEdnLNzg5mK8Q~~&x5=0&f=json"
    def start_requests(self):
      MongoObj=MongoOperate(MONGO_URI,MONGO_DATABASE,MONGO_USER,MONGO_PASS,RESPONSE)
        MongoObj.connect()
        items=MongoObj.finddata()
        for item in items:
            headers={
                'Accept-Encoding':'gzip, deflate',
                'Connection':'keep-alive',
                'Accept':'*/*',
                'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_1 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Mobile/14A403 MicroMessenger/6.5.18 NetType/WIFI Language/zh_CN',
                'Accept-Language': 'zh-cn',
                'X-Requested-With': 'XMLHttpRequest',
                'X-WECHAT-KEY': '62526065241838a5d44f7e7e14d5ffa3e87f079dc50a66e615fe9b6169c8fdde0f7b9f36f3897212092d73a3a223ffd21514b690dd8503b774918d8e86dfabbf46d1aedb66a2c7d29b8cc4f017eadee6',
                'X-WECHAT-UIN': 'MTU2MzIxNjQwMQ%3D%3D',
                'Cookie':';wxuin=1563216401;pass_ticket=oQDl45NRtfvQIxv2j2pYDSOOeflIXU7V3x1TUaOTpi6SkMp2B3fJwF6TE40ATCpU;ua_id=Wz1u21T8nrdNEyNaAAAAAOcFaBcyz4SH5DoQIVDcnao=;pgv_pvid=7103943278;sd_cookie_crttime=1501115135519;sd_userid=8661501115135519;3g_guest_id=-8872936809911279616;tvfe_boss_uuid=8ed9ed1b3a838836;mobileUV=1_15c8d374ca8_da9c8;pgv_pvi=8005854208'

            }
            biz=item["biz"]
      #主要驗證是wap_sid2;pass_ticket不一樣無所謂
            headers["Cookie"]="wap_sid2="+item["wap_sid2"]+headers["Cookie"]
            yield Request(url=self.url.format(biz=biz,index="10"),headers=headers,callback=self.parse,dont_filter=True,meta={"biz":biz,"headers":headers},)
    def parse(self, response):
        biz=response.request.meta["biz"]
        headers=response.request.meta["headers"]
        resText=json.loads(response.text)
        print(resText)
        list=json.loads(resText["general_msg_list"])
        print(list)
        yield list
        if resText["can_msg_continue"]==1:
            self.count=self.count+10
            yield Request(url=self.url.format(biz=biz,index=str(self.count)),headers=headers,callback=self.parse,dont_filter=True,meta={"biz":biz,"headers":headers})
        else:
            print("end")
  • 獲取到的數據如下圖所示:
最終捕獲的數據
  • 在爬取的過程中,有時候經過抓包,想獲取一個重定向的網頁的響應頭;但是響應頭cookies已經設置read only,我們想通過這里獲取權限值,可以通過設置Fiddler的rules來生成保存響應文件。在微信文章爬取過程中,雖然也是想通過這種方式獲取權限值。但是發覺自己是忽略了請求頭x-wechat-key和x-wechat-uin所以獲取不到。所以這種方式在該項目并不需要。但是提供一種獲取動態設置cookies值,然后重定向到新頁面的響應頭方法,比如獲取 https://mp.weixin.qq.com/mp/profile_ext?action=home
    查看FiddlerScript
  • 在Fiddler添加以下代碼,然后在桌面生成一個2.txt文件,上面保存返回的響應頭:
static function OnBeforeResponse(oSession: Session) {
      if (oSession.HostnameIs("mp.weixin.qq.com") && oSession.uriContains("/mp/profile_ext?action=home")) {
          oSession["ui-color"] = "orange";
          oSession.SaveResponse("C:\\Users\\Administrator\\Desktop\\2.txt",false);
          //oSession.SaveResponseBody("C:\\Users\\Administrator\\Desktop\\1.txt")
      }
      if (m_Hide304s && oSession.responseCode == 304) {
          oSession["ui-hide"] = "true";
      }
  }
響應頭
哈哈

源代碼的readme.md文件介紹使用的方式,需要可以直接到github上面獲取源碼,github源碼地址;喜歡的給個star喲。
其他類似文章

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內容