15K程式設計師做的小玩意,就是一個爬蟲案例,但是為啥我看完也會了!
今天在逛論壇,一位程式設計師分享了他的成果,相對來說比較簡單。所以我效仿著去試了一下,確實挺好玩,講的是多執行緒。所以今天給大家分享一下,對爬蟲有興趣的小夥伴可以好好學習一下。再給大家分享之前呢,這裡推薦下我自己建的學習交流群:148715490,不管你是小白還是大牛,小編我都挺歡迎,不定期分享乾貨,包括2017最新的企業案例學習資料和零基礎入門教程,歡迎初學和進階中的小夥伴。
案例:多執行緒爬蟲
目標:待爬取頁面URL:http://www.codingke.com/course/248?Invite_code=294973
要求:
使用requests獲取頁面資訊,用XPATH/re 做資料提取
獲取每個帖子裡的 使用者頭像連結、使用者主頁、使用者名稱、使用者性別、使用者年齡、段子內容、點贊次數、評論次數
儲存到本地json檔案內
採用多執行緒
queue(佇列物件)
queue是python中的標準庫,可以直接import queue引用,佇列是執行緒間最常用的交換資料的形式
python下多執行緒:
對於資源,加鎖是個重要的環節。因為python原生的list, dict等,都是not thread safe的。而queue,是thread safe(執行緒案例)的,因此在滿足使用條件下,建議使用佇列
初始化:class queue.Queue(maxsize) FIFO(先進先出)
常用方法:
queue.Queue.qsize() 返回佇列的大小
queue.Queue.empty() 如果佇列為空,返回True,反之返回False
queue.Queue.full() 如果佇列滿了,返回True,反之返回False
queue.Queue.get([block[, timeout]]) 從佇列中取出一個值,timeout為等待時間
建立一個“佇列”物件
import queue
myqueue = queue.Queue(maxsize = 10)
將一個值放入佇列中
myqueue.put(10)
將一個值從佇列中取出
myqueue.get()
程式碼方面小編有點懶。所以很粗糙,各位老鐵輕點噴。小編玻璃心啊。站在我的角度考慮考慮問題啊。
#!/usr/bin/python3
# -*- conding:utf-8 -*-
__author__='mayi'
"""
案例:多執行緒爬蟲
目標:待爬取頁面首頁URL:http://www.codingke.com/course/248?Invite_code=294973
要求:
1.使用requests獲取頁面資訊,用XPATH/re 做資料提取
2.獲取每個帖子裡的 使用者頭像連結、使用者主頁、使用者名稱、使用者性別、使用者年齡、段子內容、點贊次數、評論次數
3.儲存到json檔案內
4.採用多執行緒
"""
importrequests
fromlxmlimportetree
fromqueueimportQueue
importthreading
importtime
importjson
# 資料佇列
data_queue=Queue()
exitFlag_Parser=False
# 鎖
lock=threading.Lock()
classThreadCrawl(threading.Thread):
"""
爬取執行緒類
"""
def__init__(self, thread_name, page_queue):
threading.Thread.__init__(self)
self.thread_name=thread_name
self.page_queue=page_queue
self.url="http://www.qiushibaike.com/8hr/page/"
self.header={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36'}
defrun(self):
print(self.thread_name+" Starting...")
self.qiushi_spider()
print(self.thread_name+" Exiting...")
defqiushi_spider(self):
globaldata_queue
whileTrue:
# page佇列為空時,迴圈結束
ifself.page_queue.empty():
break
else:
page=self.page_queue.get()
full_url=self.url+str(page)+"/"
print(full_url)
# 多次嘗試傳送請求失敗後結束、防止死迴圈
timeout=5
whiletimeout:
try:
# 防止訪問太快
time.sleep(1)
content=requests.get(full_url, headers=self.header)
data_queue.put(content.text)
break
exceptException as e:
print(e)
timeout-=1
time.sleep(1)
classThreadParser(threading.Thread):
"""
頁面解析類
"""
def__init__(self, thread_name, file_name):
threading.Thread.__init__(self)
self.thread_name=thread_name
self.file_name=file_name
defrun(self):
# 開始
print(self.thread_name+" Starting...")
globaldata_queue, exitFlag_Parser
whilenotexitFlag_Parser:
try:
item=data_queue.get(block=False)
ifitem:
self.parse_data(item)
data_queue.task_done()
except:
pass
# 結束
print(self.thread_name+" Exiting...")
defparse_data(self, item):
"""
解析網頁函式
:param item: 網頁內容
"""
globallock
try:
html=etree.HTML(item)
# id = qiushi_tag_119336220:id均包含:qiushi_tag_
result=html.xpath('//div[contains(@id,"qiushi_tag_")]')
forresinresult:
try:
# 使用者頭像連結、使用者主頁、使用者名稱、使用者性別、使用者年齡、段子內容、點贊次數、評論次數
# 使用者頭像連結
head_url=res.xpath('.//img/@src')[0]
# 使用者主頁
home_url="http://www.qiushibaike.com"+res.xpath('.//a/@href')[0]
# 使用者名稱
user_name=res.xpath('.//h2')[0].text
# 使用者性別:匿名使用者,匹配不到性別
article_gender=res.xpath('./div/div/@class')
ifarticle_gender:
gender=article_gender[0].split()[-1].replace("Icon", "")
else:
gender=""
# 使用者年齡:匿名使用者,匹配不到年齡
article_age=res.xpath('./div/div')
ifarticle_age:
age=article_age[0].text
else:
age=0
# 段子內容
content=res.xpath('.//div[@class="content"]/span')[0].text.strip()
# 點贊次數
stats_vote=res.xpath('.//span[@class="stats-vote"]//i[@class="number"]')
ifstats_vote:
stats_vote=stats_vote[0].text.strip()
else:
stats_vote="0"
# 評論次數
stats_comments=res.xpath('.//span[@class="stats-comments"]//i[@class="number"]')
ifstats_comments:
stats_comments=stats_comments[0].text.strip()
else:
stats_comments="0"
record={
"head_url": head_url,
"home_url": home_url,
"user_name": user_name,
"gender": gender,
"age": age,
"content": content,
"stats_vote": stats_vote,
"stats_comments": stats_comments
}
with lock:
self.file_name.write(json.dumps(record, ensure_ascii=False)+",")
exceptException as e:
print(e)
exceptException as e:
print(e)
defmain():
"""
主函式
:return:
"""
# 採集的資料儲存在本地磁碟的檔名
file_name=open("糗事百科.json","a", encoding="utf-8")
# 待採集的起始頁碼
start_page=int(input("請輸入起始頁碼:"))
# 待採集的終止頁碼
end_page=int(input("請輸入終止頁碼:"))
# 定義一個page佇列
pageQueue=Queue()
forpageinrange(start_page, end_page+1):
# 頁碼入佇列
pageQueue.put(page)
# 初始化採集執行緒
crawl_threads=[]
crawl_list=["採集執行緒1","採集執行緒2","採集執行緒3"]
forthread_nameincrawl_list:
thread=ThreadCrawl(thread_name, pageQueue)
thread.start()
crawl_threads.append(thread)
# 初始化解析執行緒
parser_threads=[]
parser_list=["解析執行緒1","解析執行緒2","解析執行緒3"]
forthread_nameinparser_list:
thread=ThreadParser(thread_name, file_name)
thread.start()
parser_threads.append(thread)
# 等待列隊被清空
whilenotpageQueue.empty():
pass
# 等待所有執行緒處理完成
forthreadincrawl_threads:
thread.join()
# 等待佇列被清空
whilenotdata_queue.empty():
pass
# 通知執行緒退出
globalexitFlag_Parser
exitFlag_Parser=True
forthreadinparser_threads:
thread.join()
with lock:
file_name.close()
if__name__=='__main__':
# 執行主函式
main()
相關文章
- 我不是一個成功的人,但是我想做一個優秀的程式設計師程式設計師
- 我就差一個程式設計師了!程式設計師
- 面試了一個 5 年 Java 程式設計師,一個問題也不會。。面試Java程式設計師
- 我想成為一個真的程式設計師程式設計師
- 做一個努力的程式設計師程式設計師
- 面試一個6年 Java程式設計師,竟然問啥都不會!面試Java程式設計師
- 別問我為啥哭,只因我是一名程式設計師!程式設計師
- 作為一個程式設計師我最大的遺憾程式設計師
- 面試了一個 39 歲程式設計師後,我被罵了……面試程式設計師
- 我也 30 了,來談談程式設計師的迷茫年齡程式設計師
- 做個程式設計師程式設計師
- 我的第一個 scrapy 爬蟲爬蟲
- 別逗了,我們真的需要會程式設計的設計師嗎?程式設計
- 我是一個不會運維的後端程式設計師運維後端程式設計師
- 做什麼職業,也別做程式設計師程式設計師
- 為什麼程式設計師做外包會被瞧不起?程式設計師
- 做一個心理健康的程式設計師程式設計師
- 如何做一個理智的程式設計師程式設計師
- 我為我是個程式設計師而驕傲程式設計師
- 面試了一個 39 歲程式設計師,我有點慌……面試程式設計師
- 前端程式設計師:月薪 5K 到 5 萬,我幹了啥前端程式設計師
- 每到一個階段,都會有一個最火的程式設計師職位,目前就是前端!程式設計師前端
- 我對女生做程式設計師的一些看法程式設計師
- 我是一個iOS程式設計師iOS程式設計師
- 我是一個垃圾程式設計師程式設計師
- 我是一個混蛋程式設計師程式設計師
- 面試了一個2年程式設計師,竟然只會curd!面試程式設計師
- 做博士還是做一個專業的程式設計師?程式設計師
- 為啥程式設計師喜歡Android?程式設計師Android
- 做一個有想法的程式設計師,做一個屬於自己的神器程式設計師
- 不會填坑的程式設計師不是一個好程式設計師!程式設計師
- 當程式設計師看到美女之後?一個社會工程學的案例程式設計師
- python就是爬蟲嗎-python就是爬蟲嗎Python爬蟲
- @程式設計師,一文讓你掌握Python爬蟲!程式設計師Python爬蟲
- nodeJS做一個簡單的爬蟲NodeJS爬蟲
- 為什麼該和程式設計師約會?我有 20 個理由程式設計師
- 【譯】我是一個平庸的程式設計師程式設計師
- 我是一個失聰的程式設計師程式設計師