多執行緒爬取免費代理ip池 (給我爬)
文章目錄
- 多執行緒爬取免費代理ip池 (給我爬)
- 安裝的庫
- IP 隱藏
- 代理ip
- 多執行緒爬取
- 讀入代理ip
- 寫入代理ip
- 驗證代理ip
- 決議網頁得到代理ip
- 獲取網頁回應
- 測驗已有檔案的ip是否正確
- 多執行緒爬取
- 完整代碼
天網恢恢疏而不漏,有時候爬太多資料的時候會把自己的ip給封掉,所以呢,我左思右想,就想能不能把自己的ip給換掉,換成那種高匿ip,這樣的話,就找不到我的真實ip,這樣我就可以好好隱藏自己了哈哈哈, (注意:本博客和代碼僅可用于計算機技術學習及資料抓取、爬蟲采集等合法行為)
安裝的庫
首先我們可以打開我們的命令列,輸入以下代碼安裝這些庫,這樣才能保證我們的結果能夠正確運行,
pip install lxml requests pathos
IP 隱藏
在我們用python進行爬蟲操作的時候,如何影藏自己的ip地址呢,眾所周知,如果我們在我們的百度上直接查詢ip地址幾個字,我們就可以得到我們自己的ip地址

那如何將我們的ip地址改掉呢,其實有很多種方法,我們可以直接就把本機ip改掉,這樣的話,他做什么事情我們的ip都被改掉了,當然,我們也可以利用代碼進行修改,只需要多加一個引數proxies即可
比如現在我們找到了另一個有效的ip,我拿此來用,我只需要設定我們的proxies引數即可
# 用到的庫
import requests
# 寫入獲取到的ip地址到proxy
proxy = {
'https':'221.178.232.130:8080'
}
# 用百度檢測ip代理是否成功
url = 'https://www.baidu.com/s?'
# 請求網頁傳的引數
params={
'wd':'ip地址'
}
# 請求頭
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
}
# 發送get請求
response = requests.get(url=url,headers=headers,params=params,proxies=proxy)
print(response.text)
# 獲取回傳頁面保存到本地,便于查看
with open('ip.html','w',encoding='utf-8') as f:
f.write(response.text)
可以查看頁面是否ip地址變了,如果變了說明成功了,當然,其實我們測驗的時候,只是需要看看我們的狀態碼是否是200,如果是200,就說明我們其實已經成功了
代理ip
為了隱藏自己的ip,我們就需要用代理ip了
從IP代理的隱蔽性級別進行劃分,代理可以分為三種,即高度匿名代理、普通匿名代理和透明代理,
| 代理型別 | 代理服務器端的配置 | 描述 |
|---|---|---|
| 透明代理 | REMOTE_ADDR = Proxy IP;HTTP_VIA = Proxy IP;HTTP_X_FORWARDED_FOR = Your IP | 透明代理雖然可以直接“隱藏”你的IP地址,但是還是可以從HTTP_X_FORWARDED_FOR來查到你是誰, |
| 匿名代理 | REMOTE_ADDR = proxy IP;HTTP_VIA = proxy IP;HTTP_X_FORWARDED_FOR = proxy IP | 匿名代理比透明代理進步了一點:別人只能知道你用了代理,無法知道你是誰, |
| 高匿代理 | REMOTE_ADDR = Proxy IP;HTTP_VIA = Proxy IP;HTTP_X_FORWARDED_FOR = Random IP address | 高匿代理讓別人根本無法發現你是在用代理,所以是最好的選擇, |
接下來我們來介紹一下,如何去自動爬取代理ip,因為有時候手動去調proxy太麻煩了
我們首先給出幾個免費代理ip的網址
http://www.ip3366.net/
http://www.feidudaili.com/index/gratis/index
https://proxy.ip3366.net/free/
https://www.89ip.cn/index.html
http://www.66ip.cn/1.html
如果我們打開這些網站,我們可以看到有很多免費代理ip和他們的埠,比如

在這里面我們可以利用這些代理ip,但是有時候,這些代理ip是有問題的,所以我們在用的時候又要進行測驗,因為畢竟這些是免費的ip,是很不穩定的,我們也可以出錢買ip,這樣我們得到的ip就是穩定的,免費ip是很難穩定的,
多執行緒爬取
接下來,我就想對其進行爬取,批量爬取,一個一個測驗,將正確的存入檔案中,我們可以下次進行使用
讀入代理ip
目的其實很簡單,如果我們的檔案本身有這個ip,我們就不必要繼續寫入相同的,這樣會比較浪費時間
def read_proxy(path='ip_proxy.txt'):
if not os.path.exists(path):
f = open(path,'w')
f.close()
with open(path,'r') as f:
PROXY = f.readlines()
PROXY = [proxy.replace('\n', '') for proxy in PROXY]
return PROXY
寫入代理ip
這個也就更顯而易見了吧,就是將正確的代理ip寫入我們的檔案中,還是比較簡單的,
# 將代理ip寫入檔案
def write_proxy(proxy,path='ip_proxy.txt'):
if proxy not in PROXY:
with open('ip_proxy.txt','a+') as fp:
fp.write(proxy + '\n')
print("正在寫入 ip: {1} ".format(proxy))
print("錄入完成")
else:
print("檔案中已有相同ip,未錄入")
驗證代理ip
這里有一個很重要的代碼也就是,驗證代理ip,因為我們的ip地址并不是所有都是可用的,所以我們應該驗證他們,如果是正確的,我們再進行寫入,如果是錯誤的,那我們不會進行寫入操作,
# 驗證已得到IP的可用性
def test_proxies(proxies):
url = "https://www.1688.com/"
header = {
"User-Agent": random.choice(my_headers),
'Connection': 'close'
}
for proxy in proxies:
try:
response = requests.get(url,headers=header,proxies={"http":proxy,'https':proxy},timeout=2)
# time = response.elapsed.total_seconds()
# print(time)
if response.status_code == 200:
print('-'*15,"該代理IP可用: {0}".format(proxy),'-'*15)
write_proxy(proxy)
else:
print("該代理IP不可用: {0}".format(proxy))
except Exception as e:
print("該代理IP無效: {0}".format(proxy))
決議網頁得到代理ip
對于我們的網頁來說,里面有很多的代理ip,他們的格式都是類似的,所以我們需要從決議我們的網頁得到代理ip,然后進行我們的測驗,如果成功就會寫入進行,這里我們就需要用我們的xpath決議我們的網頁,當然,也可以用BeautifSoup
# 決議網頁,并得到網頁中的代理IP
def get_proxy(html,xpath):
selector = etree.HTML(html)
proxies = []
XPATH = xpath
for each in selector.xpath(XPATH):
# ip.append(each[0])
ip = each.xpath('./td[1]/text()')[0].strip()
port = each.xpath('./td[2]/text()')[0].strip()
proxy = ip + ':' + port
proxies.append(proxy)
# print('ip 有' ,len(proxies) , '條')
test_proxies(proxies)
獲取網頁回應
這個就更簡單了,實際上就是對我們的網頁進行回應,在用以上代碼進行決議,也是比較簡單的,不過這里面有兩個引數
# 營造請求頭,獲取網頁回應
def get_html(url_xpath,page):
header = {
"User-Agent": random.choice(my_headers),
'Connection': 'close'
}
url,xpath = url_xpath['url'],url_xpath['xpath']
# print(url,xpath)
response = requests.get(url%page, headers=header,proxies=proxies)
# print(response.text)
get_proxy(response.text ,xpath)
測驗已有檔案的ip是否正確
由于我們畢竟是免費的ip,所以來說,我們就需要對其進行再一次測驗,因為可能他很快就要失效了
def test_files(path):
proxies = read_proxy(path)
proxies = list(set(proxies))
url = "https://www.1688.com/"
header = {
"User-Agent": random.choice(my_headers),
'Connection': 'close'
}
f = open(path,'w')
for proxy in proxies:
try:
response = requests.get(url,headers=header,proxies={"http":proxy,'https':proxy},timeout=2)
# time = response.elapsed.total_seconds()
# print(time)
if response.status_code == 200:
print('-'*15,"該代理IP可用: {0}".format(proxy),'-'*15)
f.write(proxy + '\n')
else:
print("該代理IP不可用: {0}".format(proxy))
except Exception as e:
print("該代理IP無效: {0}".format(proxy))
f.close()
多執行緒爬取
其實對于這一塊來說,我們可以一個一個爬取的,但是我覺得太慢了,在這個時間效率為王的時代,我覺得我們還是有必要用一些多執行緒的,這里我們就需要用一下pathos庫,用里面的執行緒池進行一個多執行緒的爬取
pool = Pool(30)
for name,ip in ip_url.items():
# print(name,ip)
e_pages = ip['page']
total_page = [i for i in range(s_pages,e_pages + 1)]
url_xpath = [ip]*(e_pages-s_pages + 1)
pool.map(get_html,url_xpath,total_page)
print('\n'*3,name,'已經被爬完','\n'*3)
time.sleep(30)
pool.close()
pool.join()
我這里還用了30個執行緒去爬取,這樣可能極大的提高了效率,相當于一次性爬30個頁面,我覺得這可能能很大的提高我們的效率吧
不過這里關于多執行緒的知識還是需要大家去努力看看,我這里還是不詳細講了

這里出現有時候print奇奇怪怪的原因是,我們利用了多執行緒,所以每一個執行緒都是獨立的,有時候更快導致了,我們輸出有時候也會有一點點亂,但是在我們的檔案中不會,只是看起來有點奇怪哈哈
做好心理準備,爬取下來的IP,可能立馬就失效了,畢竟免費的(便宜沒什么好貨對吧,而且可能大家都在爬爬爬)
完整代碼
最后的最后呢,我還是給出完整的代碼,每個人在自己的電腦上都可以運行的,只要安裝正確那些庫,有什么問題都可以跟我討論,我最后再多嘴一句**(注意:本博客和代碼僅可用于計算機技術學習及資料抓取、爬蟲采集等合法行為)**
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# @File : ip.py
# @Time : 2021/09/30 19:32:52
# @Author : DKJ
# @Contact : 1016617094@qq.com
# @Software: VScode
# here put the import lib
import requests
from lxml import etree
import random
import os
from pathos.multiprocessing import ProcessingPool as Pool
import time
my_headers = [
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14",
"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)",
'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11',
'Opera/9.25 (Windows NT 5.1; U; en)',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)',
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12',
'Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9',
"Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Ubuntu/11.04 Chromium/16.0.912.77 Chrome/16.0.912.77 Safari/535.7",
"Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0 "
]
PROXY = []
proxies = {}
def read_proxy(path='ip_proxy.txt'):
if not os.path.exists(path):
f = open(path,'w')
f.close()
with open(path,'r') as f:
PROXY = f.readlines()
PROXY = [proxy.replace('\n', '') for proxy in PROXY]
return PROXY
# 將代理ip寫入檔案
def write_proxy(proxy,path='ip_proxy.txt'):
if proxy not in PROXY:
with open('ip_proxy.txt','a+') as fp:
fp.write(proxy + '\n')
print("正在寫入 ip: {1} ".format(proxy))
print("錄入完成")
else:
print("檔案中已有相同ip,未錄入")
# 驗證已得到IP的可用性
def test_proxies(proxies):
url = "https://www.1688.com/"
header = {
"User-Agent": random.choice(my_headers),
'Connection': 'close'
}
for proxy in proxies:
try:
response = requests.get(url,headers=header,proxies={"http":proxy,'https':proxy},timeout=2)
# time = response.elapsed.total_seconds()
# print(time)
if response.status_code == 200:
print('-'*15,"該代理IP可用: {0}".format(proxy),'-'*15)
write_proxy(proxy)
else:
print("該代理IP不可用: {0}".format(proxy))
except Exception as e:
print("該代理IP無效: {0}".format(proxy))
# 決議網頁,并得到網頁中的代理IP
def get_proxy(html,xpath):
selector = etree.HTML(html)
proxies = []
XPATH = xpath
for each in selector.xpath(XPATH):
# ip.append(each[0])
ip = each.xpath('./td[1]/text()')[0].strip()
port = each.xpath('./td[2]/text()')[0].strip()
proxy = ip + ':' + port
proxies.append(proxy)
# print('ip 有' ,len(proxies) , '條')
test_proxies(proxies)
# 營造請求頭,獲取網頁回應
def get_html(url_xpath,page):
header = {
"User-Agent": random.choice(my_headers),
'Connection': 'close'
}
url,xpath = url_xpath['url'],url_xpath['xpath']
# print(url,xpath)
response = requests.get(url%page, headers=header,proxies=proxies)
# print(response.text)
get_proxy(response.text ,xpath)
def test_files(path):
proxies = read_proxy(path)
proxies = list(set(proxies))
url = "https://www.1688.com/"
header = {
"User-Agent": random.choice(my_headers),
'Connection': 'close'
}
f = open(path,'w')
for proxy in proxies:
try:
response = requests.get(url,headers=header,proxies={"http":proxy,'https':proxy},timeout=2)
# time = response.elapsed.total_seconds()
# print(time)
if response.status_code == 200:
print('-'*15,"該代理IP可用: {0}".format(proxy),'-'*15)
f.write(proxy + '\n')
else:
print("該代理IP不可用: {0}".format(proxy))
except Exception as e:
print("該代理IP無效: {0}".format(proxy))
f.close()
if __name__ == "__main__":
requests.DEFAULT_RETRIES = 5 # 增加重試連接次數
s = requests.session()
s.keep_alive = False # 關閉多余連接
# 代理ip的爬取源地址
PATH = 'ip_proxy.txt'
test_files(PATH)
print('測驗完畢')
# time.sleep(10)
PROXY = read_proxy(PATH)
if len(PROXY) != 0:
proxy = random.choices(PROXY)
proxies['https'],proxies['http'] = proxy,proxy
ip_url = {'飛度代理':{'url':'http://www.feidudaili.com/index/gratis/index?page=%s',
'xpath':'//div[@class="section clearfix"]//table[@class="data_table"]/tbody/tr',
'page':24},
'89代理':{'url':'http://www.89ip.cn/index_%s.html',
'xpath':'//table[@class="layui-table"]/tbody/tr',
'page':11},
'齊云代理':{'url':'https://proxy.ip3366.net/free/?action=china&page=%s',
'xpath':'//*[@id="content"]/section/div[2]/table/tbody/tr',
'page':10},
'UU http代理':{'url':'http://www.uuhttp.com/index/free/index?page=%s',
'xpath':'//div[@class="dial_left fadeInLeft free_page"]//div[@class="price_table"]//tbody/tr',
'page':'600'},
'66免費代理':{'url':'http://www.66ip.cn/%s.html',
'xpath':'//div[@class="layui-row layui-col-space15"]//table/tbody/tr',
'page':1000},
'云代理':{'url':'http://www.ip3366.net/?stype=1&page=%s',
'xpath':'//div[@id="container"]//div[@id="list"]/table/tbody/tr',
'page':10}
}
# get_html(ip_url['89代理'],1)
s_pages = 1
pool = Pool(30)
for name,ip in ip_url.items():
# print(name,ip)
e_pages = ip['page']
total_page = [i for i in range(s_pages,e_pages + 1)]
url_xpath = [ip]*(e_pages-s_pages + 1)
pool.map(get_html,url_xpath,total_page)
print('\n'*3,name,'已經被爬完','\n'*3)
time.sleep(30)
pool.close()
pool.join()
最后祝大家生活愉快,國慶節快樂咯!!!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/304763.html
標籤:python
上一篇:2021-10-01
下一篇:正則運算式(一)
