本人比較喜歡段子蛾扇,平時(shí)也經(jīng)常上糗百咧织。所以這次作業(yè)也想嘗試一下爬取糗百的內(nèi)容囤捻。
網(wǎng)站鏈接:https://www.qiushibaike.com/
主要想爬取的數(shù)據(jù)有段子內(nèi)容、用戶奸披、投票數(shù)昏名、評(píng)論數(shù)、熱門評(píng)論等等阵面。其實(shí)沒(méi)有用什么特別的技巧轻局,也沒(méi)有什么反爬機(jī)制,所以比較簡(jiǎn)單膜钓,用xpath來(lái)進(jìn)行定位獲取相應(yīng)的內(nèi)容就行嗽交。
具體的步驟就不詳細(xì)說(shuō)明了,po上代碼:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import json
import time
import requests
# import pymongo
from scrapy import Selector
class BaiKe():
def __init__(self):
# 初始化爬取條數(shù)
self.num = 0
# 實(shí)例化mongo client連接對(duì)象
# client = pymongo.MongoClient('127.0.0.1', 27017)
# self.coll = client['spider']['baike']
def get_item(self):
'''返回一個(gè)初始化后的item'''
item = {}
item['content'] = '' # 主要內(nèi)容
item['id'] = '' # 唯一ID
item['person_name'] = '' # 用戶名
item['age'] = '' # 年齡
item['gender'] = '' # 性別
item['comment_num'] = '' # 評(píng)論數(shù)
item['vote_num'] = '' # 投票數(shù)
item['hot_comment'] = '' # 熱門評(píng)論
return item
def lie_biao(self, url):
'''獲取列表信息'''
# 設(shè)置請(qǐng)求的頭部信息颂斜,偽裝成瀏覽器
headers = {
'Host': 'www.qiushibaike.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
}
# 使用get請(qǐng)求訪問(wèn)url夫壁,并帶上頭部信息
r = requests.get(url, headers=headers)
# 根據(jù)返回的網(wǎng)頁(yè)信息生成一個(gè)選擇器對(duì)象
body = Selector(text=r.text)
# 獲取列表中的所有div標(biāo)簽,生成一個(gè)div選擇器列表
divs = body.xpath('//div[@id="content-left"]/div')
# 循環(huán)列表
for div in divs:
item = self.get_item()
contents = div.xpath('a[@class="contentHerf"]/div/span/text()').extract()
# 將列表信息轉(zhuǎn)換為字符串
content = '\n'.join(contents)
# 將內(nèi)容放入到字典中
item['content'] = content
# 內(nèi)容唯一ID
id = div.xpath('@id').extract()
if id:
data = re.search(r'\d+', id[0])
if data:
item['id'] = data.group()
# 用戶名
person_name = div.xpath('div[@class="author clearfix"]/a[@title]/h2/text()').extract()
if person_name:
item['person_name'] = person_name[0]
# 年齡
age = div.xpath('div[@class="author clearfix"]/div/text()').extract()
if age:
item['age'] = age[0]
# 性別
gender_class = div.xpath('div[@class="author clearfix"]/div/@class').extract()
if gender_class:
if 'women' in gender_class[0]:
item['gender'] = u'女'
else:
item['gender'] = u'男'
# 進(jìn)入詳情頁(yè)
detail_url = div.xpath('a[@class="contentHerf"]/@href').extract()
if detail_url:
url = 'https://www.qiushibaike.com' + detail_url[0]
self.get_detail(url, item)
# 分頁(yè)
next = body.xpath('//ul[@class="pagination"]/li[last()]/a/span/text()').extract()
if next and next[0].strip() == u'下一頁(yè)':
next_url = body.xpath('//ul[@class="pagination"]/li[last()]/a/@href').extract()[0]
next_url = 'https://www.qiushibaike.com' + next_url
self.lie_biao(next_url)
def get_detail(self, url, item):
'''獲取詳情信息'''
# 設(shè)置請(qǐng)求的頭部信息沃疮,偽裝成瀏覽器
headers = {
'Host': 'www.qiushibaike.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
}
# 使用get請(qǐng)求訪問(wèn)url盒让,并帶上頭部信息
r = requests.get(url, headers=headers)
# 根據(jù)返回的網(wǎng)頁(yè)信息生成一個(gè)選擇器對(duì)象
body = Selector(text=r.text)
# 投票數(shù)
vote_num = body.xpath('//span[@class="stats-vote"]/i/text()').extract()
if vote_num:
item['vote_num'] = vote_num[0]
# 評(píng)論數(shù)
comment_num = body.xpath('//span[@class="stats-comments"]/i/text()').extract()
if comment_num:
item['comment_num'] = comment_num[0]
# 最熱門的評(píng)論
hot_comment = body.xpath('//div[@class="comments-list-item"]/div[1]/a/div[@class="main-text"]/text()').extract()
if hot_comment:
item['hot_comment'] = hot_comment[0]
# 寫入文件
self.write_file(item)
# 寫入數(shù)據(jù)庫(kù)
# self.write_mongo(item)
def write_file(self, item):
'''將item寫入到文件中'''
# 將item字典轉(zhuǎn)換為json字符串
json_str = '{}\n'.format(json.dumps(dict(item),ensure_ascii=False))
# 寫入文件
with open('./baike_all.txt', 'a') as fp:
fp.write(str(json_str))
self.num += 1
print(u'已入庫(kù):', self.num, u'條。')
def write_mongo(self, item):
'''將item寫入數(shù)據(jù)庫(kù)中'''
self.coll.update({'id': item['id']}, {'$set': item}, upsert=True)
self.num += 1
print(u'已入庫(kù):', self.num, u'條司蔬。')
def run(self):
'''啟動(dòng)方法'''
url = 'https://www.qiushibaike.com/'
self.lie_biao(url)
def read_file(self):
'''文件的讀取'''
with open('./baike.txt', 'r') as fp:
for line in fp.readlines():
item = json.loads(line)
print(item['content'])
print('*'*10)
# python文件會(huì)從這個(gè)if語(yǔ)句開始執(zhí)行
if __name__ == '__main__':
# 實(shí)例化Baike類邑茄,生成bk實(shí)例
bk = BaiKe()
# 調(diào)用run方法
bk.run()
爬取的部分內(nèi)容如下: