使用python搭建代理IP池實(shí)現(xiàn)接口設(shè)置與整體調(diào)度
前言
在網(wǎng)絡(luò)爬蟲中,代理IP池是一個(gè)非常重要的組件。由于許多網(wǎng)站對單個(gè)IP的請求有限制,如果我們一直使用同一個(gè)IP去請求數(shù)據(jù),我們很快就會被封禁。因此,我們需要一個(gè)代理IP池,以便我們可以輪流使用多個(gè)代理IP,以避免被封禁的風(fēng)險(xiǎn)。
在本文中,我們將使用Python來構(gòu)建一個(gè)代理IP池。我們將使用requests和BeautifulSoup庫來從互聯(lián)網(wǎng)上抓取免費(fèi)代理IP,并將它們存儲到一個(gè)代理IP池中。然后,我們將使用這個(gè)代理IP池來訪問我們需要的數(shù)據(jù)。
本文內(nèi)容涵蓋以下幾個(gè)方面:
- 搭建免費(fèi)代理IP爬蟲
- 將獲取到的代理IP存儲到數(shù)據(jù)庫中
- 構(gòu)建一個(gè)代理IP池
- 實(shí)現(xiàn)調(diào)度器來調(diào)度代理IP池
- 實(shí)現(xiàn)帶有代理IP池的爬蟲
本文將涉及到一些網(wǎng)絡(luò)編程的知識,如果您還不熟悉這些知識,請先補(bǔ)充相關(guān)的知識。同時(shí),本文代碼也是在Python 3.8環(huán)境中運(yùn)行的。
1. 搭建免費(fèi)代理IP爬蟲
我們需要從互聯(lián)網(wǎng)上抓取免費(fèi)代理IP,這里我們使用的是站大爺代理ip網(wǎng)站上的免費(fèi)代理IP。我們將使用requests和BeautifulSoup來實(shí)現(xiàn)爬蟲。
爬蟲代碼如下所示:
import requests from bs4 import BeautifulSoup def get_proxy_ips(): """ Get the proxy IPs from zdaye.com """ url = 'https://www.zdaye.com/' headers = { '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'} html = requests.get(url, headers=headers).text soup = BeautifulSoup(html, 'html.parser') ips = soup.find_all('tr') proxy_ips = [] for ip in ips[1:]: lst = ip.text.strip().split('\n') proxy_ip = {'ip': lst[0], 'port': lst[1]} proxy_ips.append(proxy_ip) return proxy_ips
2. 將獲取到的代理IP存儲到數(shù)據(jù)庫中
我們需要將獲取到的代理IP存儲到數(shù)據(jù)庫中,以便我們在后續(xù)的處理中使用。在這里,我們使用MongoDB作為我們的數(shù)據(jù)庫,它是一個(gè)非常流行的文檔型數(shù)據(jù)庫,特別適合存儲非結(jié)構(gòu)化數(shù)據(jù)。
我們需要安裝pymongo庫來連接MongoDB。安裝命令如下:
pip install pymongo
接下來,我們需要定義一個(gè)函數(shù)來將代理IP存儲到MongoDB中。代碼如下所示:
from pymongo import MongoClient def save_proxy_ips(proxy_ips): """ Save the proxy IPs to MongoDB """ client = MongoClient('mongodb://localhost:27017/') db = client['proxy_ips'] coll = db['ips'] coll.delete_many({}) coll.insert_many(proxy_ips)
上面的代碼將獲取到的代理IP列表作為參數(shù)傳遞,然后將代理IP列表存儲到名為“proxy_ips”的數(shù)據(jù)庫中的“ips”集合中。
3. 構(gòu)建一個(gè)代理IP池
現(xiàn)在我們已經(jīng)有了一個(gè)爬蟲和一個(gè)數(shù)據(jù)庫,接下來我們將構(gòu)建一個(gè)代理IP池。在這個(gè)代理IP池中,我們將從數(shù)據(jù)庫中隨機(jī)選擇一個(gè)代理IP,并使用它來訪問我們需要的數(shù)據(jù)。如果代理IP無法使用,則需要從池中刪除該代理IP。如果池中的代理IP數(shù)量太少,則需要重新從互聯(lián)網(wǎng)上抓取免費(fèi)代理IP,并將其存儲到數(shù)據(jù)庫中。
實(shí)現(xiàn)代碼如下所示:
import random class ProxyPool: def __init__(self, threshold=5): """ Initialize the proxy pool """ self.threshold = threshold self.client = MongoClient('mongodb://localhost:27017/') self.db = self.client['proxy_ips'] self.coll = self.db['ips'] def get_proxy_ip(self): """ Get a random proxy IP from the pool """ count = self.coll.count_documents({}) if count == 0: return None proxy_ips = self.coll.find({}, {'_id': 0}) ips = [proxy_ip for proxy_ip in proxy_ips] proxy_ip = random.choice(ips) ip = 'http://' + proxy_ip['ip'] + ':' + proxy_ip['port'] return {'http': ip} def delete_proxy_ip(self, proxy_ip): """ Delete the proxy IP from the pool """ self.coll.delete_one(proxy_ip) def check_proxy_ip(self, proxy_ip): """ Check if the given proxy IP is available """ proxies = {'http': 'http://' + proxy_ip['ip'] + ':' + proxy_ip['port']} try: requests.get('https://www.baidu.com/', proxies=proxies, timeout=5) return True except: return False def update_pool(self): """ Update the proxy pool """ count = self.coll.count_documents({}) if count < self.threshold: proxy_ips = get_proxy_ips() save_proxy_ips(proxy_ips)
上面的代碼中,我們定義了一個(gè)名為ProxyPool的類。這個(gè)類有四個(gè)方法:
- get_proxy_ip:從代理IP池中獲取一個(gè)隨機(jī)代理IP。
- delete_proxy_ip:從代理IP池中刪除一個(gè)代理IP。
- check_proxy_ip:檢查給定的代理IP是否可用。
- update_pool:檢查池中的代理IP數(shù)量是否低于閾值,如果低于閾值,則從互聯(lián)網(wǎng)上獲取新的代理IP列表,并將其存儲到數(shù)據(jù)庫中。
值得注意的是,我們使用了MongoDB作為代理IP池的存儲介質(zhì)。因此,我們需要安裝MongoDB數(shù)據(jù)庫,并確保它在運(yùn)行。
4. 實(shí)現(xiàn)調(diào)度器來調(diào)度代理IP池
為了使用代理IP池,我們需要實(shí)現(xiàn)一個(gè)調(diào)度器來調(diào)度代理IP池。調(diào)度器需要獲取一個(gè)隨機(jī)的代理IP,并將其傳遞給請求。如果請求返回狀態(tài)碼為403(表示無權(quán)訪問),則需要從代理IP池中刪除該代理IP,并重新獲取一個(gè)代理IP。
實(shí)現(xiàn)代碼如下所示:
class Scheduler: def __init__(self): self.proxy_pool = ProxyPool() def request(self, url): """ Send a request to the given url using a random proxy IP """ while True: proxy_ip = self.proxy_pool.get_proxy_ip() if proxy_ip is None: return None try: response = requests.get(url, proxies=proxy_ip, timeout=5) if response.status_code == 200: return response elif response.status_code == 403: self.proxy_pool.delete_proxy_ip(proxy_ip) else: continue except: self.proxy_pool.delete_proxy_ip(proxy_ip) def run(self): """ Run the scheduler to update the proxy pool """ self.proxy_pool.update_pool()
上面的代碼中,我們定義了一個(gè)名為Scheduler的類。這個(gè)類有兩個(gè)方法:
- request:使用隨機(jī)代理IP發(fā)送請求。
- run:運(yùn)行調(diào)度器來更新代理IP池。
當(dāng)我們向調(diào)度器發(fā)出請求時(shí),調(diào)度器將從代理IP池中獲取一個(gè)隨機(jī)代理IP,并將其作為請求的代理IP。如果請求返回狀態(tài)碼為200,則說明代理IP可用,可以將響應(yīng)返回給調(diào)用者。如果狀態(tài)碼為403,則需要從代理IP池中刪除該代理IP,并重新獲取一個(gè)代理IP。如果請求發(fā)生異常,則也需要從代理IP池中刪除該代理IP。
5. 實(shí)現(xiàn)帶有代理IP池的爬蟲
現(xiàn)在我們已經(jīng)有了一個(gè)代理IP池和一個(gè)調(diào)度器,接下來我們將實(shí)現(xiàn)一個(gè)帶有代理IP池的爬蟲。在這個(gè)爬蟲中,我們將使用調(diào)度器來調(diào)度代理IP池,并將獲取到的數(shù)據(jù)存儲到MongoDB數(shù)據(jù)庫中。
實(shí)現(xiàn)代碼如下所示:
import time class Spider: def __init__(self): self.scheduler = Scheduler() self.client = MongoClient('mongodb://localhost:27017/') self.db = self.client['data'] self.coll = self.db['info'] def crawl(self): """ Crawl data using the proxy pool """ while True: response = self.scheduler.request('https://www.example.com/') if response is not None: html = response.text # parse the html to get the data data = {} self.coll.insert_one(data) time.sleep(1) def run(self): """ Run the spider to crawl data """ while True: self.scheduler.run() self.crawl() time.sleep(10)
上面的代碼中,我們定義了一個(gè)名為Spider的類。這個(gè)類有兩個(gè)方法:
- crawl:使用代理IP池來爬取數(shù)據(jù),并將數(shù)據(jù)存儲到MongoDB數(shù)據(jù)庫中。
- run:運(yùn)行爬蟲來爬取數(shù)據(jù)。
當(dāng)我們運(yùn)行爬蟲時(shí),它將首先運(yùn)行調(diào)度器來更新代理IP池。然后,它將使用代理IP池來爬取數(shù)據(jù),并將數(shù)據(jù)存儲到MongoDB數(shù)據(jù)庫中。最后,它將休眠10秒鐘,然后重復(fù)這個(gè)過程。
總結(jié)
在本文中,我們使用Python來構(gòu)建了一個(gè)代理IP池。我們首先使用requests和BeautifulSoup庫來從互聯(lián)網(wǎng)上抓取免費(fèi)代理IP,并將其存儲到MongoDB數(shù)據(jù)庫中。然后,我們構(gòu)建了一個(gè)代理IP池,從中隨機(jī)選擇代理IP,并使用它來訪問我們需要的數(shù)據(jù)。如果代理IP無法使用,則從池中刪除該代理IP。如果池中的代理IP數(shù)量太少,則重新從互聯(lián)網(wǎng)上獲取新的代理IP列表。
最后,我們實(shí)現(xiàn)了一個(gè)帶有代理IP池的爬蟲,使用調(diào)度器來調(diào)度代理IP池。該爬蟲將獲取數(shù)據(jù),并將數(shù)據(jù)存儲到MongoDB數(shù)據(jù)庫中。
以上就是使用python搭建代理IP池實(shí)現(xiàn)接口設(shè)置與整體調(diào)度的詳細(xì)內(nèi)容,更多關(guān)于python搭建代理IP池的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Django高并發(fā)負(fù)載均衡實(shí)現(xiàn)原理詳解
這篇文章主要介紹了Django高并發(fā)負(fù)載均衡實(shí)現(xiàn)原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Python連接MySQL數(shù)據(jù)庫的四種方法
用?Python?連接到?MySQL?數(shù)據(jù)庫的方法不是很系統(tǒng),實(shí)際中有幾種不同的連接方法,而且不是所有的方法都能與不同的操作系統(tǒng)很好地配合,本文涵蓋了四種方法,你可以用它們來連接你的Python應(yīng)用程序和MySQL,需要的朋友可以參考下2024-08-08詳解Python 爬取13個(gè)旅游城市,告訴你五一大家最愛去哪玩?
這篇文章主要介紹了Python 爬取13個(gè)旅游城市,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05網(wǎng)站滲透常用Python小腳本查詢同ip網(wǎng)站
這篇文章主要介紹了網(wǎng)站滲透常用Python小腳本查詢同ip網(wǎng)站,需要的朋友可以參考下2017-05-05python 如何快速找出兩個(gè)電子表中數(shù)據(jù)的差異
下面小編就為大家?guī)硪黄猵ython 如何快速找出兩個(gè)電子表中數(shù)據(jù)的差異。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05