案例:pchome24h 爬蟲 - 搜索功能 多線程爬蟲
Last updated
Was this helpful?
Last updated
Was this helpful?
Was this helpful?
import requests #先引用requests
import time
#目標網址為:https://ecshweb.pchome.com.tw/search/v3.3/all/results?q=關鍵字
#請求範例:https://ecshweb.pchome.com.tw/search/v3.3/all/results?q=%E8%97%8D%E8%8A%BD%E9%9F%B3%E9%9F%BF&page=1&sort=sale/dc
#建構網址
keyword = "藍芽音響"
url = "https://ecshweb.pchome.com.tw/search/v3.3/all/results?q="+keyword+"&page=1&sort=sale/dc"
#嘗試請求
rs = requests.get(url=url)
#輸出結果
data = rs.text
print(data)
import json #引用json函式
json_data = json.loads(data)
page_max = json_data['totalPage'] #取得所有頁數
all_items = [] #先宣告一個 所有商品的保存陣列
for n in range(page_max): #針對頁數做一個迴圈
page_num = n + 1 #因為 頁碼會從0開始計算
if page_num > 20: #只爬到第20頁就停止,本次教學 不含換ip教學 所以先這樣
break
# 建構網址
#將頁碼與字串合併,因為 頁數為 整數int型別,所以要括一個format來進行轉換
url = "https://ecshweb.pchome.com.tw/search/v3.3/all/results?q=" + keyword + "&page="+format(page_num)+"&sort=sale/dc"
# 嘗試請求
rs = requests.get(url=url)
# 輸出結果
data = rs.text
try:#做一個例外處理,如果出現錯誤可以避免卡住
page_data = json.loads(data)#轉換json格式
products = page_data['prods']#取得商品列表
for pro in products:
all_items.append(pro)#將商品保存進商品陣列
# print(data)
print("目前進度頁數 {}/{} 已保存:{}個商品".format(page_num,page_max,len(all_items)))#字串整合的應用
except Exception as e: #輸出的錯誤名稱叫e
print(e) #印出錯誤內容
print(data) #印出這一頁所抓取的值
time.sleep(1)#記得要休息一秒再抓取,不然會被封ip
#保存結果
all_items_json = json.dumps(all_items) #將資料轉為json格式字串
fp = open("result.txt",'w',encoding="utf-8")#建立檔案
fp.write(all_items_json)#寫入
fp.close()#關閉檔案
queue.get() 取得一個任務 # 抓出一個觀眾
queue.put() 插入一個任務 # 有一個觀眾隊伍領號碼牌
queue.qsize() 計算隊伍有多長
基本上只會用到這三個功能Que = queue.Queue() #初始化隊伍
#將所有的頁數,分發進入隊伍
for n in range(page_max): #針對頁數做一個迴圈
page_num = n + 1 #因為 頁碼會從0開始計算
Que.put(page_num) #將頁碼送進去隊伍
from threading import Threadt = Thread(target="要觸發的函數") #target這個參數為你要多線程運作的函式
t.start() #一定要有start,不然線程會不工作
def Run_24hshop_Page(): #定義要做為 Thread函式的 函式
global all_items #確保這裡的 all_items收集陣列為全域的
while Que.qsize() > 1: #因為是專門為消化隊伍所使用,所以在隊伍沒有結束之前 都要不斷運作著
page_num = Que.get() #用get取得要爬的頁數
#以下參考 前一篇的單線程爬蟲
url = "https://ecshweb.pchome.com.tw/search/v3.3/all/results?q=" + keyword + "&page=" + format(
page_num) + "&sort=sale/dc"
# 嘗試請求
rs = requests.get(url=url)
# 輸出結果
data = rs.text
try: # 做一個例外處理,如果出現錯誤可以避免卡住
page_data = json.loads(data) # 轉換json格式
products = page_data['prods'] # 取得商品列表
for pro in products:
all_items.append(pro) # 將商品保存進商品陣列
print("頁數:{} 爬取成功!".format(page_num))
except Exception as e: # 輸出的錯誤名稱叫e
# print()
print("頁數:{} 爬取失敗 被擋ip".format(page_num))
# print(e) # 印出錯誤內容
# print(data) # 印出這一頁所抓取的值
time.sleep(1) # 記得要休息一秒再抓取,不然會被封ip
#運作Thread
#每初始化一個線程就代表一個線程的產生
#所以要產生如 10 個線程 那就直接用迴圈產生30次就好了
Thread_Team = []# 【線程工作收集陣列】 用來收集工作中的線程好確認是不是都工作完成
for x in range(10):
t = Thread(target=Run_24hshop_Page) #target這個參數為你要多線程運作的函式
t.start() #一定要有start,不然線程會不工作
Thread_Team.append(t) #要記得將線程加入到上面準備好的 【線程工作收集陣列】
#等待所有線程工作完成
for t in Thread_Team:
t.join() #join這個功能代表,等待 線程工作結束,如果沒有結束就會一直卡在這裡,透過這個特性,來完成等待任務完工
初始化線程完成 一共 10 個線程
頁數:3 爬取成功!
頁數:2 爬取成功!
頁數:9 爬取成功!
頁數:4 爬取成功!
頁數:5 爬取成功!
頁數:1 爬取成功!
頁數:7 爬取成功!
頁數:8 爬取成功!
頁數:10 爬取成功!
頁數:6 爬取成功!
頁數:11 爬取成功!
頁數:12 爬取成功!
頁數:14 爬取成功!
頁數:16 爬取成功!
頁數:13 爬取成功!
頁數:17 爬取成功!
頁數:18 爬取成功!
頁數:19 爬取成功!
頁數:15 爬取成功!
頁數:20 爬取成功!
頁數:21 爬取成功!
頁數:22 爬取成功!
頁數:24 爬取成功!
頁數:26 爬取成功!
頁數:23 爬取成功!
頁數:25 爬取成功!
頁數:27 爬取失敗 被擋ip
頁數:28 爬取成功!
頁數:30 爬取成功!
頁數:29 爬取成功!
頁數:31 爬取失敗 被擋ip
頁數:32 爬取成功!
頁數:34 爬取失敗 被擋ip
頁數:35 爬取失敗 被擋ip