由于部分代碼含有微博賬號(hào)、數(shù)據(jù)庫(kù)等信息,此處只展示部分Python。有需要的同學(xué)可以聯(lián)系我(不包含數(shù)據(jù)庫(kù)建庫(kù)代碼,因?yàn)橐徊糠植僮髦苯踊贜avicat可視化數(shù)據(jù)庫(kù)軟" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁(yè) > 營(yíng)銷資訊 > 網(wǎng)站運(yùn)營(yíng) > 新浪微博爬蟲實(shí)現(xiàn)(附核心Python代碼)

新浪微博爬蟲實(shí)現(xiàn)(附核心Python代碼)

時(shí)間:2023-05-20 08:42:02 | 來源:網(wǎng)站運(yùn)營(yíng)

時(shí)間:2023-05-20 08:42:02 來源:網(wǎng)站運(yùn)營(yíng)

新浪微博爬蟲實(shí)現(xiàn)(附核心Python代碼):如何爬取新浪微博數(shù)據(jù)?

由于部分代碼含有微博賬號(hào)、數(shù)據(jù)庫(kù)等信息,此處只展示部分Python。有需要的同學(xué)可以聯(lián)系我(不包含數(shù)據(jù)庫(kù)建庫(kù)代碼,因?yàn)橐徊糠植僮髦苯踊贜avicat可視化數(shù)據(jù)庫(kù)軟件進(jìn)行的)。

步驟一:剖析網(wǎng)頁(yè)結(jié)構(gòu)

此環(huán)節(jié)是最基礎(chǔ)的部分,也是較為重要的部分。關(guān)鍵就是在復(fù)雜的網(wǎng)頁(yè)結(jié)構(gòu)中尋找到自己想要的信息。此處選擇的是網(wǎng)頁(yè)版移動(dòng)微博的爬取,網(wǎng)址為https://m.weibo.cn/

首先使用谷歌瀏覽器登陸自己的微博賬號(hào),隨便打開某位博主的微博頁(yè)面,觀察網(wǎng)頁(yè)結(jié)構(gòu)。此處以Jerry_寅子的微博為例。首先我們?yōu)g覽他的微博,發(fā)現(xiàn)隨著鼠標(biāo)的滑動(dòng),會(huì)不斷加載出來新的頁(yè)面。這就是常見的異步加載。每一次加載新的內(nèi)容都相當(dāng)于新的頁(yè)面,而這樣的內(nèi)容往往不像教程中所說的放在Network的Doc中,而是XHR的Js文件中,這里的Js即為基于XML的異步JavaScript(AJAX)文件。

打開谷歌瀏覽器的后臺(tái)控制器(頁(yè)面處右鍵-檢查),點(diǎn)開Network中的XHR,刷新界面重新載入,點(diǎn)開Perview界面,可以看到JS代碼,一層一層的點(diǎn)開就會(huì)看到微博信息所在的地方。這就是我們需要爬取的信息。

具有微博內(nèi)容的JS代碼

步驟二:模擬登陸獲取JS

在熟悉JS的結(jié)構(gòu)之后,我們所要做的就是將代碼訪問模擬真人登錄,去抓取JS。這里有兩種方法,一種是模擬登陸,另外一種是模擬瀏覽器。

模擬登陸:在移動(dòng)端微博的登錄界面,輸入自己的用戶名和密碼,登錄微博移動(dòng)端。

payload = { 'username': '156****1997', 'password': '**********'} #設(shè)置請(qǐng)求頭文件信息 header_init = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36', 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 'Accept-Encoding':'gzip, deflate, br', 'Connection':'close', 'Referer':'https://weibo.com/askcliff?is_all=1' } #微博登陸頁(yè)URL url_login='https://passport.weibo.cn/signin/login' #設(shè)置一個(gè)會(huì)話對(duì)象 s = requests.Session() #以post形式提交登陸用戶名和密碼 s.post(url=url_login, data=payload, headers=header_init)另外一種是模擬瀏覽器登錄,利用瀏覽器的Cookies信息,這個(gè)信息可以在網(wǎng)頁(yè)的后臺(tái)控制中很容易找到,注意要以字典的形式存儲(chǔ)在變量中。[代碼:Cookies示例(在XHR的JS中的Header Requests可以找到)]

#微博內(nèi)容抓取頁(yè)URL url_init = url_base+'&page={}' #設(shè)置Cookie的內(nèi)容 cookie={ 'MLOGIN':'1', 'M_WEIBOCN_PARAMS':'luicode%3D10000011%26lfid%3D100103type%253D3%2526q%253D%25E5%25AF%2585%25E5%25AD%2590%2526t%253D0%26featurecode%3D20000320%26oid%3D3900004206849232%26fid%3D1005053628359543%26uicode%3D10000011&page={}', 'SCF':'AkhONeuuFcGAlAz0kgavz1wRbp1fz7ZGn0Xn_zPHzoa0B_VbPTNxInVDSaycKttiCUPGwlxaxxqJG', 'SUB':'_2A252C9fsDeRhGeNI41QZ-CrEyzqIHXVV9_mkrDV6PUJbkdAKLW_CkW1NSDUIJok_9iLiEAocyWlucWgHT-UKNQiO', 'SUHB':'0A0JidXol5dQPP', 'WEIBOCN_FROM':'1110006030', '_T_WM':'28789df2dacda9b86d0a2ffa60adbfe8', }一般來說,模擬瀏覽器比模擬登陸的方式用時(shí)更短。

這部分另外一個(gè)關(guān)鍵就是注意URL的規(guī)律,也就是所要訪問頁(yè)面的網(wǎng)址。因?yàn)槲覀円トs,所以不是地址欄的網(wǎng)址,而是在js的headers中的url。對(duì)于這種異步加載的來說,一般前面的網(wǎng)頁(yè)是固定的,只有后面的page會(huì)有不同。采用url_init = url_base+'&page={}'即可表現(xiàn)這一規(guī)律。

步驟三:獲取特定內(nèi)容

獲取網(wǎng)頁(yè)的內(nèi)容之后,下一步就是解析網(wǎng)頁(yè)格式,獲取特定內(nèi)容。由于JS的JSON文件類似字典,非常之有規(guī)律,所以獲取內(nèi)容非常容易。使用jd = json.loads(res.text)將網(wǎng)頁(yè)內(nèi)容解析成JSON格式,然后按照不同字段獲取內(nèi)容。

# 發(fā)博人creen_name = jd['data']['cards'][count]['mblog']['user']['screen_name']result['微博用戶'].append(screen_name)# 這部分是獲取微博用戶的文本內(nèi)容# 發(fā)表時(shí)間a = ('/''+jd['data']['cards'][count]['mblog']['created_at']+'/'').count('-')if a == 2:date = datetime.strptime(jd['data']['cards'][count]['mblog']['created_at'],'%Y-%m-%d')datesrt = date.strftime('%Y-%m-%d')if a == 1:date = datetime.strptime(jd['data']['cards'][count]['mblog']['created_at'],'%m-%d')datesrt = date.strftime('2018'+'-%m-%d')if a == 0:datesrt = '今天或昨天'result['發(fā)博日期'].append(datesrt)這部分是關(guān)于發(fā)博日期的獲取。之所以用了很多判斷,是它的時(shí)間呈現(xiàn)方式導(dǎo)致。新浪微博中會(huì)有類似于“1小時(shí)前”、“今天”“5天前”等非規(guī)范的時(shí)間表達(dá)方式。(規(guī)范的方式為xxxx年xx月xx日)

后續(xù)針對(duì)其他字段的處理方式同上。

def PageData(url,cookie,header): #提交請(qǐng)求獲取要抓取的頁(yè)面信息 res = requests.get(url=url, cookies=cookie, headers=header) #讀取頁(yè)面內(nèi)容 jd = json.loads(res.text) count = -1 result = {} result['id'] = [] result['微博用戶'] = [] result['發(fā)博日期'] = [] result['微博文本'] = [] result['附帶圖片鏈接'] = [] result['微博鏈接'] = [] result['點(diǎn)贊數(shù)'] = [] result['評(píng)論數(shù)'] = [] result['轉(zhuǎn)發(fā)數(shù)'] = [] for i in jd['data']['cards']: count = count + 1 if jd['data']['cards'][count]['card_type'] == 9: #發(fā)博人 screen_name = jd['data']['cards'][count]['mblog']['user']['screen_name'] result['微博用戶'].append(screen_name) #發(fā)表時(shí)間 a = ('/''+jd['data']['cards'][count]['mblog']['created_at']+'/'').count('-') if a == 2: date = datetime.strptime(jd['data']['cards'][count]['mblog']['created_at'],'%Y-%m-%d') datesrt = date.strftime('%Y-%m-%d') if a == 1: date = datetime.strptime(jd['data']['cards'][count]['mblog']['created_at'],'%m-%d') datesrt = date.strftime('2018'+'-%m-%d') if a == 0: datesrt = '今天或昨天' result['發(fā)博日期'].append(datesrt) #微博內(nèi)容 text = jd['data']['cards'][count]['mblog']['text'] text = filter_emoji(text,restr='') soup = BeautifulSoup(text,'html.parser') text = soup.get_text() result['微博文本'].append(text) #微博所附圖片鏈接 if 'original_pic' in jd['data']['cards'][count]['mblog'].keys(): original_pic = jd['data']['cards'][count]['mblog']['original_pic'] else: original_pic = '無圖片鏈接' result['附帶圖片鏈接'].append(original_pic) #微博網(wǎng)頁(yè)鏈接 html = jd['data']['cards'][count]['scheme'] result['微博鏈接'].append(html) #點(diǎn)贊數(shù)量 attitudes_count = jd['data']['cards'][count]['mblog']['attitudes_count'] result['點(diǎn)贊數(shù)'].append(attitudes_count) #評(píng)論數(shù)量 comments_count = jd['data']['cards'][count]['mblog']['comments_count'] result['評(píng)論數(shù)'].append(comments_count) #轉(zhuǎn)發(fā)數(shù)量 reposts_count = jd['data']['cards'][count]['mblog']['reposts_count'] result['轉(zhuǎn)發(fā)數(shù)'].append(reposts_count) return result

步驟四:整理數(shù)據(jù),入庫(kù)

步驟三將獲取的信息整理到了字典之中,接下來就是根據(jù)字段來寫入數(shù)據(jù)庫(kù)。此部分較多的涉及到數(shù)據(jù)庫(kù)的知識(shí)。因?yàn)檫@里使用pymysql建表比較復(fù)雜,容易出錯(cuò),所以建表環(huán)節(jié)在navicat中進(jìn)行。

def to_sql(weibo_total,dbname): #寫入數(shù)據(jù)庫(kù) conn = pymysql.connect(user='spider',password='****',host='***.***.**.**',port=3306,database='spider',use_unicode=True,charset="utf8") cs = conn.cursor() #整理字典數(shù)據(jù) for i in range(len(weibo_total['微博用戶'])): data = '' for k in weibo_total.keys(): data = (data + '/'' + '{}' + '/'' + ',').format(weibo_total[k][i]) #data = '/"'+ data[:-1] + '/"' #SQL語(yǔ)句執(zhí)行 sql = ("""INSERT INTO %s VALUES (%s)""") % (dbname,data[:-1]) cs.execute(sql) cs.execute("SELECT * FROM %s"%dbname) conn.commit() print(cs.fetchall()) conn.close()由以上代碼所示,首先鏈接數(shù)據(jù)庫(kù),然后整理儲(chǔ)存在字典中的數(shù)據(jù),之后執(zhí)行操作將數(shù)據(jù)存入數(shù)據(jù)庫(kù)。此代碼適用于所有網(wǎng)頁(yè)版移動(dòng)端微博數(shù)據(jù)的爬取。

Appendix 1:微博文本全文無法顯示問題的解決

當(dāng)我們爬取微博的時(shí)候,我們會(huì)遇到這樣一個(gè)問題,某些博主發(fā)了很長(zhǎng)的一段文字,在實(shí)際我們?yōu)g覽微博的時(shí)候,我們需要點(diǎn)擊“全文”這個(gè)按鈕才可以瀏覽全文。所以這樣導(dǎo)致我們爬取的數(shù)據(jù)也只是被折疊之后的內(nèi)容。

關(guān)于這個(gè)問題的解決辦法,與解決異步加載的思路大同小異,因?yàn)辄c(diǎn)擊全文按鈕之后相當(dāng)于也是加載了新的頁(yè)面。關(guān)鍵在于尋找跳轉(zhuǎn)頁(yè)面的鏈接。

“微博全文無法顯示”問題的解決代碼
如代碼所示,對(duì)于判定為折疊的代碼,由于其跳轉(zhuǎn)的網(wǎng)頁(yè)鏈接比較規(guī)律,所以直接跳轉(zhuǎn)到微博界面獲取全文本即可。

Appendix 2:Emjio表情的過濾

在第一次嘗試將數(shù)據(jù)入庫(kù)的時(shí)候,發(fā)現(xiàn)了帶有Emjio表情的文本會(huì)報(bào)錯(cuò)。這是由于編碼的問題,正常我們使用utf編碼,但是emjio表情是utfbm4,其編碼位數(shù)比utf要長(zhǎng)。原則上這個(gè)問題可以通過改變編碼方式來解決,但是我在配置環(huán)境的時(shí)候遇到了種種問題,所以最后采取了將其過濾掉的方式。代碼如下圖所示。

#過濾emoji表情def filter_emoji(desstr,restr=''): try: co = re.compile(u'[/U00010000-/U0010ffff]') except re.error: co = re.compile(u'[/uD800-/uDBFF][/uDC00-/uDFFF]') return co.sub(restr, desstr)如有錯(cuò)誤或理解不到位之處,還希望大家及時(shí)指正哇。畢竟代碼比較久遠(yuǎn),有些細(xì)節(jié)不太清楚了~

下次更新預(yù)告:利用卷積實(shí)現(xiàn)人臉識(shí)別(附Python核心代碼)

關(guān)鍵詞:核心,實(shí)現(xiàn),爬蟲

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉