當前位置:吉日网官网 - 紀念幣收藏 - python怎麽抓取微信閱

python怎麽抓取微信閱

抓取微信公眾號的文章

壹.思路分析

目前所知曉的能夠抓取的方法有:

1、微信APP中微信公眾號文章鏈接的直接抓取(/s?__biz=MjM5MzU4ODk2MA==&mid=2735446906&idx=1&sn=ece37deaba0c8ebb9badf07e5a5a3bd3&scene=0#rd)

2、通過微信合作方搜狗搜索引擎(/),發送相應請求來間接抓取

第1種方法中,這種鏈接不太好獲取,而且他的規律不是特別清晰。

因此本文采用的是方法2----通過給 weixin.sogou.com 發送即時請求來實時解析抓取數據並保存到本地。

二.爬取過程

1、首先在搜狗的微信搜索頁面測試壹下,這樣能夠讓我們的思路更加清晰

在搜索引擎上使用微信公眾號英文名進行“搜公眾號”操作(因為公眾號英文名是公眾號唯壹的,而中文名可能會有重復,同時公眾號名字壹定要完全正確,不然可能搜到很多東西,這樣我們可以減少數據的篩選工作,只要找到這個唯壹英文名對應的那條數據即可),即發送請求到'/weixin?type=1&query=%s&ie=utf8&_sug_=n&_sug_type_= ' % ?'python',並從頁面中解析出搜索結果公眾號對應的主頁跳轉鏈接。

2.獲取主頁入口內容

使用request , urllib,urllib2,或者直接使用webdriver+phantomjs等都可以

這裏使用的是request.get()的方法獲取入口網頁內容

[python]?view plain?copy

#?爬蟲偽裝頭部設置?

self.headers?=?{'User-Agent':?'Mozilla/5.0?(Windows?NT?6.3;?WOW64;?rv:51.0)?Gecko/20100101?Firefox/51.0'}?

#?設置操作超時時長?

self.timeout?=?5?

#?爬蟲模擬在壹個request.session中完成?

self.s?=?requests.Session()?

[python]?view plain?copy

#搜索入口地址,以公眾為關鍵字搜索該公眾號?

def?get_search_result_by_keywords(self):?

self.log('搜索地址為:%s'?%?self.sogou_search_url)?

return?self.s.get(self.sogou_search_url,?headers=self.headers,?timeout=self.timeout).content?

3.獲取公眾號地址

從獲取到的網頁內容中,得到公眾號主頁地址, 這壹步驟有很多方法, beautifulsoup、webdriver,直接使用正則,pyquery等都可以

這裏使用的是pyquery的方法來查找公眾號主頁入口地址

[python]?view plain?copy

#獲得公眾號主頁地址?

def?get_wx_url_by_sougou_search_html(self,?sougou_search_html):?

doc?=?pq(sougou_search_html)?

#print?doc('p[class="tit"]')('a').attr('href')?

#print?doc('div[class=img-box]')('a').attr('href')?

#通過pyquery的方式處理網頁內容,類似用beautifulsoup,但是pyquery和jQuery的方法類似,找到公眾號主頁地址?

return?doc('div[class=txt-box]')('p[class=tit]')('a').attr('href')?

4.獲取公眾號主頁的文章列表

首先需要加載公眾號主頁,這裏用的是phantomjs+webdriver, 因為這個主頁的內容需要JS 渲染加載,采用之前的方法只能獲得靜態的網頁內容

[python]?view plain?copy

#使用webdriver?加載公眾號主頁內容,主要是js渲染的部分?

def?get_selenium_js_html(self,?url):?

browser?=?webdriver.PhantomJS()

browser.get(url)

time.sleep(3)

#?執行js得到整個頁面內容?

html?=?browser.execute_script("return?document.documentElement.outerHTML")?

return?html?

得到主頁內容之後,獲取文章列表,這個文章列表中有我們需要的內容

[python]?view plain?copy

#獲取公眾號文章內容?

def?parse_wx_articles_by_html(self,?selenium_html):?

doc?=?pq(selenium_html)?

print?'開始查找內容msg'?

return?doc('div[class="weui_media_box?appmsg"]')?

#有的公眾號僅僅有10篇文章,有的可能多壹點?

#return?doc('div[class="weui_msg_card"]')#公眾號只有10篇文章文章的?

5.解析每壹個文章列表,獲取我們需要的信息

6.處理對應的內容

包括文章名字,地址,簡介,發表時間等

7.保存文章內容

以html的格式保存到本地

同時將上壹步驟的內容保存成excel 的格式

8.保存json數據

這樣,每壹步拆分完,爬取公眾號的文章就不是特別難了。

三、源碼

第壹版源碼如下:

[python]?view plain?copy

#!/usr/bin/python?

#?coding:?utf-8?

import?sys?

reload(sys)?

sys.setdefaultencoding('utf-8')?

from?urllib?import?quote?

from?pyquery?import?PyQuery?as?pq?

from?selenium?import?webdriver?

import?requests?

import?time?

import?re?

import?json?

import?os?

class?weixin_spider:?

def?__init__(self,?kw):?

'?構造函數?'?

self.kw?=?kw?

#?搜狐微信搜索鏈接?

#self.sogou_search_url?=?'/weixin?type=1&query=%s&ie=utf8&_sug_=n&_sug_type_='?%?quote(self.kw)?

self.sogou_search_url?=?'/weixin?type=1&query=%s&ie=utf8&s_from=input&_sug_=n&_sug_type_='?%?quote(self.kw)?

#?爬蟲偽裝?

self.headers?=?{'User-Agent':?'Mozilla/5.0?(Windows?NT?10.0;?WOW64;?rv:47.0)?Gecko/20100101?FirePHP/0refox/47.0?FirePHP/0.7.4.1'}?

#?操作超時時長?

self.timeout?=?5?

self.s?=?requests.Session()?

def?get_search_result_by_kw(self):?

self.log('搜索地址為:%s'?%?self.sogou_search_url)?

return?self.s.get(self.sogou_search_url,?headers=self.headers,?timeout=self.timeout).content?

def?get_wx_url_by_sougou_search_html(self,?sougou_search_html):?

'?根據返回sougou_search_html,從中獲取公眾號主頁鏈接?'?

doc?=?pq(sougou_search_html)?

#print?doc('p[class="tit"]')('a').attr('href')?

#print?doc('div[class=img-box]')('a').attr('href')?

#通過pyquery的方式處理網頁內容,類似用beautifulsoup,但是pyquery和jQuery的方法類似,找到公眾號主頁地址?

return?doc('div[class=txt-box]')('p[class=tit]')('a').attr('href')?

def?get_selenium_js_html(self,?wx_url):?

'?執行js渲染內容,並返回渲染後的html內容?'?

browser?=?webdriver.PhantomJS()

browser.get(wx_url)

time.sleep(3)

#?執行js得到整個dom

html?=?browser.execute_script("return?document.documentElement.outerHTML")?

return?html?

def?parse_wx_articles_by_html(self,?selenium_html):?

'?從selenium_html中解析出微信公眾號文章?'?

doc?=?pq(selenium_html)?

return?doc('div[class="weui_msg_card"]')?

def?switch_arctiles_to_list(self,?articles):?

'?把articles轉換成數據字典?'?

articles_list?=?[]?

i?=?1?

if?articles:?

for?article?in?articles.items():?

self.log(u'開始整合(%d/%d)'?%?(i,?len(articles)))?

articles_list.append(self.parse_one_article(article))?

i?+=?1?

#?break?

return?articles_list?

def?parse_one_article(self,?article):?

'?解析單篇文章?'?

article_dict?=?{}?

article?=?article('.weui_media_box[id]')?

title?=?article('h4[class="weui_media_title"]').text()?

self.log('標題是:?%s'?%?title)?

url?=?''?+?article('h4[class="weui_media_title"]').attr('hrefs')?

self.log('地址為:?%s'?%?url)?

summary?=?article('.weui_media_desc').text()?

self.log('文章簡述:?%s'?%?summary)?

date?=?article('.weui_media_extra_info').text()?

self.log('發表時間為:?%s'?%?date)?

pic?=?self.parse_cover_pic(article)?

content?=?self.parse_content_by_url(url).html()?

contentfiletitle=self.kw+'/'+title+'_'+date+'.html'?

self.save_content_file(contentfiletitle,content)?

return?{?

'title':?title,?

'url':?url,?

'summary':?summary,?

'date':?date,?

'pic':?pic,?

'content':?content?

}?

def?parse_cover_pic(self,?article):?

'?解析文章封面圖片?'?

pic?=?article('.weui_media_hd').attr('style')?

p?=?re.compile(r'background-image:url(.?)')?

rs?=?p.findall(pic)?

self.log(?'封面圖片是:%s?'?%?rs[0]?if?len(rs)?>?0?else?'')?

return?rs[0]?if?len(rs)?>?0?else?''?

def?parse_content_by_url(self,?url):?

'?獲取文章詳情內容?'?

page_html?=?self.get_selenium_js_html(url)?

return?pq(page_html)('#js_content')?

def?save_content_file(self,title,content):?

'?頁面內容寫入文件?'?

with?open(title,?'w')?as?f:?

f.write(content)?

def?save_file(self,?content):?

'?數據寫入文件?'?

with?open(self.kw+'/'+self.kw+'.txt',?'w')?as?f:?

f.write(content)?

def?log(self,?msg):?

'?自定義log函數?'?

print?u'%s:?%s'?%?(time.strftime('%Y-%m-%d?%H:%M:%S'),?msg)?

def?need_verify(self,?selenium_html):?

'?有時候對方會封鎖ip,這裏做壹下判斷,檢測html中是否包含id=verify_change的標簽,有的話,代表被重定向了,提醒過壹陣子重試?'?

return?pq(selenium_html)('#verify_change').text()?!=?''?

def?create_dir(self):?

'創建文件夾'?

if?not?os.path.exists(self.kw):

os.makedirs(self.kw)

def?run(self):?

'?爬蟲入口函數?'?

#Step?0?:?創建公眾號命名的文件夾?

self.create_dir()?

#?Step?1:GET請求到搜狗微信引擎,以微信公眾號英文名稱作為查詢關鍵字?

self.log(u'開始獲取,微信公眾號英文名為:%s'?%?self.kw)?

self.log(u'開始調用sougou搜索引擎')?

sougou_search_html?=?self.get_search_result_by_kw()?

#?Step?2:從搜索結果頁中解析出公眾號主頁鏈接?

self.log(u'獲取sougou_search_html成功,開始抓取公眾號對應的主頁wx_url')?

wx_url?=?self.get_wx_url_by_sougou_search_html(sougou_search_html)?

self.log(u'獲取wx_url成功,%s'?%?wx_url)?

#?Step?3:Selenium+PhantomJs獲取js異步加載渲染後的html?

self.log(u'開始調用selenium渲染html')?

selenium_html?=?self.get_selenium_js_html(wx_url)?

#?Step?4:?檢測目標網站是否進行了封鎖?

if?self.need_verify(selenium_html):?

self.log(u'爬蟲被目標網站封鎖,請稍後再試')?

else:?

#?Step?5:?使用PyQuery,從Step?3獲取的html中解析出公眾號文章列表的數據?

self.log(u'調用selenium渲染html完成,開始解析公眾號文章')?

articles?=?self.parse_wx_articles_by_html(selenium_html)?

self.log(u'抓取到微信文章%d篇'?%?len(articles))?

#?Step?6:?把微信文章數據封裝成字典的list?

self.log(u'開始整合微信文章數據為字典')?

articles_list?=?self.switch_arctiles_to_list(articles)?

#?Step?7:?把Step?5的字典list轉換為Json?

self.log(u'整合完成,開始轉換為json')?

data_json?=?json.dumps(articles_list)?

#?Step?8:?寫文件?

self.log(u'轉換為json完成,開始保存json數據到文件')?

self.save_file(data_json)?

self.log(u'保存完成,程序結束')?

#?main?

if?__name__?==?'__main__':?

gongzhonghao=raw_input(u'輸入要爬取的公眾號')?

if?not?gongzhonghao:?

gongzhonghao='python6359'?

weixin_spider(gongzhonghao).run()?

第二版代碼:

對代碼進行了壹些優化和整改,主要:

1.增加了excel存貯

2.對獲取文章內容規則進行修改

3.豐富了註釋

本程序已知缺陷: 如果公眾號的文章內容包括視視頻,可能會報錯。

[python]?view plain?copy

#!/usr/bin/python?

#?coding:?utf-8?

  • 上一篇:關於市場營銷的思考
  • 下一篇:床下藏刀是好是壞呢
  • copyright 2024吉日网官网