- 💂 個人網站:【 摸魚游戲】【神級代碼資源網站】【導航大全】
- 🤟 一站式輕松構建小程序、Web網站、移動應用:👉注冊地址
- 🤟 基于Web端打造的:👉輕量化工具創作平臺
- 💅 想尋找共同學習交流,摸魚劃水的小伙伴,請點擊【全棧技術交流群】
項目背景
本文檔詳細介紹了一個網絡爬蟲項目的準備和實現過程。該項目的目標是從百度圖片搜索中獲取圖片鏈接并下載圖片。此類爬蟲項目通常用于收集大量的圖片數據,以便用于訓練各種人工智能模型,特別是計算機視覺模型。計算機視覺領域的研究需要大量的圖像數據來訓練和測試模型,以便實現圖像分類、對象檢測、圖像生成等功能。
一、項目準備
環境配置
在開始編寫爬蟲之前,確保已經完成以下環境配置:
Python安裝: 確保已安裝Python 3.x版本。Python是一種功能強大且易于學習的編程語言,適合于各種編程任務,包括網絡爬蟲開發。
需要的庫: Python有一個龐大的第三方庫生態系統,我們將使用幾個核心庫來開發我們的爬蟲:
- requests: 用于發送HTTP請求和處理響應。
- json: 用于處理JSON格式的數據。
- urllib: 提供了在網絡上獲取數據的一些功能,我們主要用來進行URL編碼。
- os: 提供了與操作系統交互的功能,用于創建文件夾等文件操作。
- time: 提供了時間相關的功能,例如休眠程序以及計時等。
可以使用以下命令通過pip安裝這些庫:
pip install requests
如果你使用的是Anaconda等集成環境,可以使用conda命令:
conda install requests
這些庫將幫助我們處理HTTP請求、解析和存儲數據,以及進行一些基本的系統操作。
二、爬蟲設計與實現
爬蟲設計思路
目標網站分析
本爬蟲目標是從百度圖片搜索獲取圖片鏈接并下載。百度圖片搜索返回的結果是JSON格式的數據,其中包含了圖片的縮略圖鏈接。
數據獲取流程
- 構建百度圖片搜索的URL,通過GET請求獲取JSON數據。
- 解析JSON數據,提取縮略圖鏈接。
- 下載圖片到本地存儲。
代碼實現
初始化爬蟲類(BaiduImageSpider)
import requests
import json
from urllib import parse
import os
import timeclass BaiduImageSpider(object):def __init__(self):self.json_count = 0 # 請求到的json文件數量(一個json文件包含30個圖像文件)self.url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=5179920884740494226&ipn=rj&ct' \'=201326592&is=&fp=result&queryWord={' \'}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=©right=&word={' \'}&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&nojc=&pn={' \'}&rn=30&gsm=1e&1635054081427= 'self.directory = r"C:\價值一個億\python-mini-projects\projects\baidutupian\{}" # 存儲目錄 這里需要修改為自己希望保存的目錄 {}不要丟self.header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3','Accept-Language': 'en-US,en;q=0.9','Referer': 'https://image.baidu.com'}
創建存儲文件夾
# 創建存儲文件夾def create_directory(self, name):self.directory = self.directory.format(name)# 如果目錄不存在則創建if not os.path.exists(self.directory):os.makedirs(self.directory)self.directory += r'\{}'
獲取圖像鏈接
# 獲取圖像鏈接
def get_image_link(self, url):list_image_link = []strhtml = requests.get(url, headers=self.header) # Get方式獲取網頁數據print(f"Response content for URL {url}:\n{strhtml.text}\n")try:jsonInfo = json.loads(strhtml.text)except json.JSONDecodeError:print("Error decoding JSON")return list_image_linkif 'data' in jsonInfo:for index in range(len(jsonInfo['data'])):if 'thumbURL' in jsonInfo['data'][index]:list_image_link.append(jsonInfo['data'][index]['thumbURL'])else:print("No 'data' key in the response JSON")return list_image_link
下載圖片
# 下載圖片
def save_image(self, img_link, filename):try:res = requests.get(img_link, headers=self.header)if res.status_code == 404:print(f"圖片 {img_link} 下載出錯")else:with open(filename, "wb") as f:f.write(res.content)print("存儲路徑:" + filename)except requests.RequestException as e:print(f"Error downloading image: {e}")
主運行函數
# 入口函數
def run(self):searchName = input("查詢內容:")searchName_parse = parse.quote(searchName) # 編碼self.create_directory(searchName)pic_number = 0 # 圖像數量for index in range(self.json_count):pn = index * 30request_url = self.url.format(searchName_parse, searchName_parse, str(pn))list_image_link = self.get_image_link(request_url)for link in list_image_link:pic_number += 1self.save_image(link, self.directory.format(str(pic_number) + '.jpg'))time.sleep(1) # 休眠1秒,防止封ipprint(searchName + "----圖像下載完成--------->")
三、代碼詳解
__init__
方法
init 方法用于初始化爬蟲類的屬性。在這個方法中,我們定義了以下幾個重要的屬性:
- json_count: 用于指定要請求的JSON文件數量,每個JSON文件包含多個圖像條目。
- url: 百度圖片搜索的API URL,包含了多個參數用于構造請求。
- directory: 存儲下載圖片的目錄路徑。這個路徑在 create_directory 方法中被初始化和修改。
- header: 請求頭信息,包括用戶代理、接受語言和引用頁,用于模擬瀏覽器發送請求。
create_directory
方法
create_directory 方法根據提供的名稱創建存儲圖片的文件夾。具體步驟如下:
- 將 directory 屬性格式化為指定的存儲目錄路徑。
- 使用 os.makedirs() 方法創建多層目錄,如果目錄不存在的話。
- 將 directory 屬性更新為包含圖片文件名格式的路徑,以便后續保存圖片時直接在該路徑下生成文件。
get_image_link
方法
get_image_link 方法負責發送GET請求獲取百度圖片搜索返回的JSON數據,并解析數據提取圖片的縮略圖鏈接。具體步驟如下:
- 使用 requests.get() 方法發送GET請求,獲取包含圖片信息的JSON數據。
- 嘗試解析返回的JSON數據,如果解析失敗則捕獲 json.JSONDecodeError 異常并打印錯誤信息。
- 如果JSON數據中包含 data 鍵,遍歷數據條目并提取每個條目中的 thumbURL(縮略圖鏈接),將其添加到 list_image_link 列表中。
- 如果JSON數據中不存在 data 鍵,則打印相應的錯誤信息并返回空列表。
save_image
方法
save_image 方法用于下載圖片到本地存儲。具體步驟如下:
- 使用 requests.get() 方法發送GET請求,獲取包含圖片數據的響應。
- 檢查響應狀態碼,如果返回的狀態碼是404,則打印錯誤信息表示圖片下載失敗。
- 如果響應正常,將圖片數據寫入以指定文件名 filename 打開的二進制文件中(使用 “wb” 模式)。
- 打印存儲圖片的路徑信息,表示圖片已成功保存到本地。
run
方法
run 方法是爬蟲的主運行函數,負責處理用戶輸入的查詢內容,循環獲取圖片鏈接并下載到本地存儲。具體步驟如下:
- 提示用戶輸入要查詢的內容,并對用戶輸入的內容進行URL編碼,以便構造百度圖片搜索的查詢URL。
- 調用 create_directory 方法創建存儲圖片的目錄,目錄名與用戶輸入的查詢內容相關聯。
- 初始化 pic_number 變量,用于記錄已下載的圖片數量。
- 使用循環從0到 json_count (設定的請求的JSON文件數量)遍歷,構造不同頁數的百度圖片搜索URL,發送請求并獲取圖片鏈接。
- 遍歷獲取的圖片鏈接列表,逐個下載圖片到本地存儲,并在每次下載后休眠1秒以防止IP被封禁。
- 下載完成后打印提示信息,指示所有圖片已成功下載并存儲到指定目錄中。
以上詳細解釋了每個方法在爬蟲實現中的作用和具體實現步驟,確保了爬蟲能夠有效地從百度圖片搜索中獲取指定數量的圖片并保存到本地。
四、亮數據代理IP的使用
為什么需要代理IP
在爬取網站數據時,頻繁的請求會被網站識別為異常流量,可能導致IP被封禁。使用代理IP可以隱藏真實IP,降低被封禁的風險。
如何在爬蟲中配置代理IP
可以使用第三方代理IP服務商提供的代理IP池,例如requests庫中的proxies參數。這里我采用的是亮數據IP代理服務。
修改代碼以支持代理IP
在請求中添加代理IP,例如:
proxies = {'http': 'http://user:password@proxy_ip:port','https': 'https://user:password@proxy_ip:port',
}
requests.get(url, headers=self.header, proxies=proxies)
五、完整代碼及運行結果
以下是完整的Python代碼實現:
# -*- coding:utf8 -*-
import requests
import json
from urllib import parse
import os
import timeclass BaiduImageSpider(object):def __init__(self):self.json_count = 0 # 請求到的json文件數量(一個json文件包含30個圖像文件)self.url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=5179920884740494226&ipn=rj&ct' \'=201326592&is=&fp=result&queryWord={' \'}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=©right=&word={' \'}&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&nojc=&pn={' \'}&rn=30&gsm=1e&1635054081427= 'self.directory = r"C:\價值一個億\python-mini-projects\projects\baidutupian\{}" # 存儲目錄 這里需要修改為自己希望保存的目錄 {}不要丟self.header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3','Accept-Language': 'en-US,en;q=0.9','Referer': 'https://image.baidu.com'}# 創建存儲文件夾def create_directory(self, name):self.directory = self.directory.format(name)# 如果目錄不存在則創建if not os.path.exists(self.directory):os.makedirs(self.directory)self.directory += r'\{}'# 獲取圖像鏈接def get_image_link(self, url):list_image_link =[]strhtml = requests.get(url, headers=self.header) # Get方式獲取網頁數據print(f"Response content for URL {url}:\n{strhtml.text}\n")try:jsonInfo = json.loads(strhtml.text)except json.JSONDecodeError:print("Error decoding JSON")return list_image_linkif 'data' in jsonInfo:for index in range(len(jsonInfo['data'])):if 'thumbURL' in jsonInfo['data'][index]:list_image_link.append(jsonInfo['data'][index]['thumbURL'])else:print("No 'data' key in the response JSON")return list_image_link# 下載圖片def save_image(self, img_link, filename):try:res = requests.get(img_link, headers=self.header)if res.status_code == 404:print(f"圖片 {img_link} 下載出錯")else:with open(filename, "wb") as f:f.write(res.content)print("存儲路徑:" + filename)except requests.RequestException as e:print(f"Error downloading image: {e}")# 入口函數def run(self):searchName = input("查詢內容:")searchName_parse = parse.quote(searchName) # 編碼self.create_directory(searchName)pic_number = 0 # 圖像數量for index in range(self.json_count):pn = index * 30request_url = self.url.format(searchName_parse, searchName_parse, str(pn))list_image_link = self.get_image_link(request_url)for link in list_image_link:pic_number += 1self.save_image(link, self.directory.format(str(pic_number) + '.jpg'))time.sleep(1) # 休眠1秒,防止封ipprint(searchName + "----圖像下載完成--------->")if __name__ == '__main__':spider = BaiduImageSpider()spider.json_count = 10 # 定義下載10組圖像,也就是三百張spider.run()
演示爬蟲的運行
運行以上代碼,按照提示輸入查詢內容,爬蟲將開始從百度圖片搜索下載相關圖片。
下載的圖片展示
六、總結
本文詳細介紹了如何使用Python編寫一個簡單的爬蟲,用于從百度圖片搜索下載圖片。通過分析目標網站、設計爬蟲流程、實現代碼以及配置代理IP,使得爬蟲能夠有效地獲取圖片數據。通過本項目,讀者可以學習到基本的爬蟲原理和實現方法,同時也了解到了如何處理異常情況和優化爬蟲效率的方法。