前言
之前寫的微博爬蟲系列還沒寫完步淹,想起來(lái)繼續(xù)寫下去贾富。近期看了下爬取微信公眾號(hào)文章的方法,也寫了相關(guān)的代碼崇决,之后再看看寫成博客吧~
本篇主要針對(duì)怎么對(duì)指定博文下的評(píng)論進(jìn)行爬取材诽。
準(zhǔn)備寫的內(nèi)容:
微博熱門內(nèi)容及榜單的博文爬取 微博爬蟲系列之微博榜單博文爬取
定向關(guān)鍵詞及指定用戶博文爬取 微博爬蟲系列之關(guān)鍵詞及指定用戶博文爬取
博文評(píng)論爬取 微博爬蟲系列之博文評(píng)論爬取
微博用戶信息爬取
針對(duì)博文評(píng)論的爬取,采用的仍然是微博網(wǎng)頁(yè)版https://weibo.cn恒傻,在爬取時(shí)仍然需要cookies
脸侥,獲取方式可參照微博爬蟲系列之關(guān)鍵詞及指定用戶博文爬取。
這里隨便選用一個(gè)人民日?qǐng)?bào)的微博博文進(jìn)行評(píng)論的爬取盈厘。首先需要獲取博文的評(píng)論頁(yè)數(shù)睁枕,由于微博的一些反爬措施,并不能完全爬取到所有頁(yè)面沸手。為了盡可能地爬取多一些評(píng)論外遇,這里將評(píng)論熱門頁(yè)面與默認(rèn)頁(yè)面都爬取下來(lái)。
import re
from urllib import request
cookies = '你的cookies'
headers = {
"user-agent": get_random_ua(),
'Cookie' : cookies,
}
page_res = requests.get(url, headers = headers)
查看網(wǎng)頁(yè)源代碼契吉,可以看到點(diǎn)擊查看更多熱門的地方以及寫著有多少頁(yè)評(píng)論的地方:
hot_rank = re.search(r'查看更多熱門', page_res.text)
all_page = re.search(r'/> 1/(\d+)頁(yè)</div>', page_res.text)
if all_page:
all_page = all_page.group(1)
all_page = int(all_page)
all_page = all_page if all_page <= 50 else 50
if hot_rank:
hot_url = url.replace('comment', 'comment/hot')
page_urls.append(hot_url)
for page_num in range(2, all_page + 1):
page_url = hot_url.replace('page=1', 'page={}'.format(page_num))
page_urls.append(page_url)
for page_num in range(2, all_page + 1):
page_url = url.replace('page=1', 'page={}'.format(page_num))
page_urls.append(page_url)
通過這樣的方式跳仿,盡可能多地爬取評(píng)論數(shù)據(jù)。當(dāng)然這樣也會(huì)出現(xiàn)重復(fù)評(píng)論的情況捐晶,并且也不能完全爬取所有評(píng)論菲语。目前想到的方法就只能盡可能地多爬一些妄辩,爬取后去重。
在獲取了所有頁(yè)面后谨究,開始爬取每一頁(yè)的評(píng)論內(nèi)容恩袱。分析網(wǎng)頁(yè)源代碼可以看到每一個(gè)評(píng)論的標(biāo)記是<div class = "c" id = ""></div>
對(duì)上面獲取到的url進(jìn)行循環(huán)爬取評(píng)論頁(yè)面內(nèi)容,下面用第一頁(yè)作為例子胶哲,用
lxml.etree
進(jìn)行解析與定位畔塔。
from lxml import etree
res = requests.get(url, headers = headers)
tree_node = etree.HTML(res.text.encode('utf-8'))
comment_nodes = tree_node.xpath('//div[@class="c" and contains(@id,"C_")]')
通過這樣子就可以定位到評(píng)論部分,返回的comment_nodes
是一個(gè)列表鸯屿,每個(gè)元素是一個(gè)評(píng)論的元素澈吨,每個(gè)評(píng)論內(nèi)的內(nèi)容可以看源代碼:
這里假設(shè)只爬取評(píng)論用戶id、評(píng)論用戶名寄摆、評(píng)論id谅辣、評(píng)論內(nèi)容、點(diǎn)贊數(shù)婶恼,其他項(xiàng)來(lái)源這些也是一樣的(在上面就是來(lái)自網(wǎng)頁(yè))桑阶。
## 評(píng)論用戶id
comment_user_url = comment_node.xpath('.//a[contains(@href,"/u/")]/@href')
## 這里是因?yàn)橛械挠脩鬷d貌似沒有/u/,還有的不是數(shù)字
if comment_user_url:
comment_user_id = re.search(r'/u/(\d+)', comment_user_url[0]).group(1)
else:
comment_user_url = comment_node.xpath('.//a[contains(@href,"/")]/@href')
if comment_user_url:
comment_user_id = re.search(r'/(.*)', comment_user_url[0]).group(1)
## 評(píng)論用戶名
comment_user_name = str(comment_node.xpath('./a/text()')[0])
## 評(píng)論id
comment_id = str(comment_node.xpath('./@id')[0])
## 評(píng)論內(nèi)容
content = extract_comment_content(etree.tostring(comment_node, encoding='unicode'))
## 點(diǎn)贊數(shù)
like_num = comment_node.xpath('.//a[contains(text(),"贊[")]/text()')[-1]
comment_item['like_num'] = int(re.search('\d+', like_num).group())
這里還會(huì)涉及到可能有的評(píng)論會(huì)有評(píng)論配圖的情況勾邦,可以對(duì)應(yīng)的下載圖片蚣录。假設(shè)出現(xiàn)評(píng)論配圖時(shí),會(huì)有評(píng)論配圖
的字眼:
##### 保存照片
def savePics(picUrl, filename , path):
headers = {
"user-agent": get_random_ua(),
}
# 目錄不存在眷篇,就新建一個(gè)
if not os.path.exists(path):
os.makedirs(path)
picID = picUrl.split('/')[-1].split('?')[0].split('.')[0]
Suffix = picUrl.split('/')[-1].split('?')[0].split('.')[-1]
pic_path = ''.join([path, '/', filename, '.', Suffix])
req = request.Request(picUrl, headers = headers)
data = request.urlopen(req, timeout=30).read()
f = open(pic_path, 'wb')
f.write(data)
f.close()
if '評(píng)論配圖' in content:
comment_pic_url = etree.tostring(comment_node, encoding='unicode').split('class="ctt">', maxsplit=1)[1].split('舉報(bào)', maxsplit=1)[0]
comment_pic_url = re.search(r'<a href="(.*)">評(píng)論配圖', comment_pic).group(1)
savePics(comment_pic_url , filename = 'filename', path = 'your_path')
到這里爬取微博博文評(píng)論數(shù)據(jù)的操作就結(jié)束啦~ 其他的看自己的需求寫完整的代碼即可萎河。在爬取過程中可能會(huì)出現(xiàn)爬不到的情況,可以用一些判斷語(yǔ)句跳過這些爬不到的情況蕉饼,爬取的時(shí)候也需要稍微停一下不然會(huì)被封號(hào)虐杯。之后再接著寫爬取微博博文系列的最后一篇吧~