首先我們來到目標站點:https://www.qiushibaike.com/text/ ,往下拖動鼠標我們可以看到一共只有13頁的數據,因此我們需要找到請求這些數據的URL,並找到這些URL的提交規律。
**1、**打開chrome的開發者工具,切換到Network後刷新頁面,觀察到服務器返回給我們的東西里只有第一個請求URL:https://www.qiushibaike.com/text/ 裏有我們所需要的數據,切換到Response可以找到所需要的數據,如下圖所示:
接着我們點擊下一頁獲取更多的信息,並找到對相應的URL爲:https://www.qiushibaike.com/text/page/2/ ,對URL進行比對分析後我們可以發現其中變化的字段爲page後的數字,即頁碼數,由此我們可以得到一個簡化的URL爲:https://www.qiushibaike.com/text/page/{“頁碼數”}/ ,接下來我們開始寫爬蟲程序。
**2、**由Response中的信息可知,我們所提取的數據在某些節點中,爲了能夠更好的解析頁面信息,此處我們使用XPath解析庫來提取節點,然後再調用相應方法獲取它的正文內容或者屬性值,此外我們還藉助chrome瀏覽器的XPath Helper插件來輔助檢查我們所寫的匹配規則是否正確。比如以提取用戶名爲例,如下圖所示:
**3.**對於用戶名,用戶性別、年齡、及段子好笑數可通過以上方法提取,但是對於內容這部分,有時需點擊“查看全文”按鈕才能查看全部內容,此時會跳轉到另一個頁面,比如下面這個:
爲了提取文章的全部內容,我們需先按照上圖方法獲取它的鏈接後再發送請求,在新頁面繼續用XPath來提取,如下圖:
**4.**知道提取規則後,我們開始寫爬蟲程序。
程序主代碼:qiushi.py
from config import *
from lxml import etree
import pymongo
client = pymongo.MongoClient(MONGO_URL, connect=False)
class QiuShiSprider():
def __init__(self):
self.url_temp="https://www.qiushibaike.com/text/page/{}/"
self.headers={"User-Agent":set_user_agent()}
def get_url_list(self):
return [self.url_temp.format(i) for i in range(1,14)]
def parse_url(self,url):
response=requests.get(url,headers=self.headers)
return response.content.decode()
def get_content_list(self,html_str):
html=etree.HTML(html_str)
div_list=html.xpath("//div[@id='content-left']/div")
for div in div_list:
item={}
# 用戶名
item["author_name"]=div.xpath(".//div[contains(@class,'author')]/a/h2/text()")
item["author_name"] = [i.replace("\n", "") for i in item["author_name"]]
item["author_name"] = item["author_name"][0] if len(item["author_name"]) > 0 else None
# 發佈者性別
item["author_gender"]=div.xpath(".//div[contains(@class,'articleGender')]/@class")
item["author_gender"] =item["author_gender"][0].split(" ")[-1].replace("Icon","") if len(item["author_gender"])>0 else None
# 發佈者年紀
item["author_age"]=div.xpath(".//div[contains(@class,'articleGender')]/text()")
item["author_age"]=item["author_age"][0] if len(item["author_age"])>0 else None
# 段子內容
content_all= div.xpath(".//div[@class='content']/span[@class='contentForAll']/text()")# 段子內容
if len(content_all)>0:
content_url="https://www.qiushibaike.com"+div.xpath(".//a[@class='contentHerf']/@href")[0]
content_str = self.parse_url(content_url)
content_html = etree.HTML(content_str)
item["content"] = content_html.xpath("//div[@class='content']/text()") # 段子內容
else:
item["content"] = div.xpath(".//div[@class='content']/span/text()")
item["content"]=[i.replace("\n","") for i in item["content"]]
#好笑數
item["stats_vote"] = div.xpath(".//span[@class='stats-vote']/i/text()")
item["stats_vote"]=item["stats_vote"][0] if len(item["stats_vote"])>0 else None
self.save_to_mongo(item)
def save_to_mongo(self,content_list):
db = client[taget_DB]
if db[taget_TABLE].update_one(content_list, {'$set': content_list}, upsert=True):
print('Successfully Saved to Mongo', content_list)
def run(self):
#1.url_list
url_list=self.get_url_list()
#2.遍歷,發送請求,獲取響應
for url in url_list:
html_str=self.parse_url(url)
#3.提取數據
self.get_content_list(html_str)
if __name__ == '__main__':
qiushi=QiuShiSprider()
qiushi.run()
輔助程序:config.py,用於連接MongoDB,及設置隨機請求UA以應對反爬
import random
MONGO_URL = 'localhost'
taget_DB = "QIUSHI"
taget_TABLE = "QIUSHI"
def set_user_agent():
USER_AGENTS = [
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
"Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
"Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
"Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5"
]
user_agent = random.choice(USER_AGENTS)
return user_agent
**5.**爬取結果如下圖: