获得代理ippython_Python搭建代理IP池实现获取IP的方法
使用爬蟲(chóng)時(shí),大部分網(wǎng)站都有一定的反爬措施,有些網(wǎng)站會(huì)限制每個(gè) IP 的訪問(wèn)速度或訪問(wèn)次數(shù),超出了它的限制你的 IP 就會(huì)被封掉。對(duì)于訪問(wèn)速度的處理比較簡(jiǎn)單,只要間隔一段時(shí)間爬取一次就行了,避免頻繁訪問(wèn);而對(duì)于訪問(wèn)次數(shù),就需要使用代理 IP 來(lái)幫忙了,使用多個(gè)代理 IP 輪換著去訪問(wèn)目標(biāo)網(wǎng)址可以有效地解決問(wèn)題。
目前網(wǎng)上有很多的代理服務(wù)網(wǎng)站提供代理服務(wù),也提供一些免費(fèi)的代理,但可用性較差,如果需求較高可以購(gòu)買付費(fèi)代理,可用性較好。
因此我們可以自己構(gòu)建代理池,從各種代理服務(wù)網(wǎng)站中獲取代理 IP,并檢測(cè)其可用性(使用一個(gè)穩(wěn)定的網(wǎng)址來(lái)檢測(cè),最好是自己將要爬取的網(wǎng)站),再保存到數(shù)據(jù)庫(kù)中,需要使用的時(shí)候再調(diào)用。
本文介紹的則是構(gòu)建代理 IP 池的第一步:獲取 IP
使用的庫(kù):requests、pyquery
幾個(gè)能提供免費(fèi)代理的代理服務(wù)網(wǎng)站(排名不分先后):
廠商名稱
地址
66代理
http://www.66ip.cn/
西刺代理
https://www.xicidaili.com
全網(wǎng)代理
http://www.goubanjia.com
云代理
http://www.ip3366.net
IP海
http://www.iphai.com
快代理
https://www.kuaidaili.com
免費(fèi)代理IP庫(kù)
http://ip.jiangxianli.com
代理服務(wù)網(wǎng)站 Crawler
代理獲取的相關(guān)代碼,把從每個(gè)網(wǎng)站提取 IP 的方法都放到一起,然后運(yùn)行時(shí)只要調(diào)用相關(guān)方法即可
為了實(shí)現(xiàn)靈活,將獲取代理的一個(gè)個(gè)方法統(tǒng)一定義一個(gè)規(guī)范,如統(tǒng)一定義以 crawl 開(kāi)頭,這樣擴(kuò)展的時(shí)候只需要添加 crawl 開(kāi)頭的方法即可
在這里實(shí)現(xiàn)了幾個(gè)示例,如抓取代理 66、西刺代理、云代理、快代理 四個(gè)免費(fèi)代理網(wǎng)站,這些方法都定義成生成器,通過(guò) yield 返回。首先將網(wǎng)頁(yè)獲取,然后用 PyQuery 解析,解析出 IP 加端口形式的代理再返回
crawler.py
import json
import re
from utils import get_page
from pyquery import PyQuery as pq
# 元類
class ProxyMetaclass(type):
def __new__(cls, name, bases, attrs):
count = 0
attrs['__CrawlFunc__'] = []
for k, v in attrs.items():
if 'crawl_' in k:
attrs['__CrawlFunc__'].append(k)
count += 1
attrs['__CrawlFuncCount__'] = count
return type.__new__(cls, name, bases, attrs)
class Crawler(object, metaclass=ProxyMetaclass):
def get_proxies(self, callback):
proxies = []
for proxy in eval("self.{}()".format(callback)):
print('成功獲取到代理', proxy)
proxies.append(proxy)
return proxies
def crawl_daili66(self, page_count=4):
start_url = 'http://www.66ip.cn/{}.html'
urls = [start_url.format(page) for page in range(1, page_count + 1)]
for url in urls:
print('Crawling', url)
html = get_page(url)
if html:
doc = pq(html)
trs = doc('.containerbox table tr:gt(0)').items()
for tr in trs:
ip = tr.find('td:nth-child(1)').text()
port = tr.find('td:nth-child(2)').text()
yield ':'.join([ip, port])
def crawl_xicidaili(self):
for i in range(1, 3):
start_url = 'http://www.xicidaili.com/nn/{}'.format(i)
headers = {
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Host':'www.xicidaili.com',
'Referer':'http://www.xicidaili.com/nn/3',
'Upgrade-Insecure-Requests':'1',
}
html = get_page(start_url, options=headers)
if html:
find_trs = re.compile('
(.*?)', re.S)trs = find_trs.findall(html)
for tr in trs:
find_ip = re.compile('
(\d+\.\d+\.\d+\.\d+)')re_ip_address = find_ip.findall(tr)
find_port = re.compile('
(\d+)')re_port = find_port.findall(tr)
for address,port in zip(re_ip_address, re_port):
address_port = address+':'+port
yield address_port.replace(' ','')
def crawl_ip3366(self):
for i in range(1, 4):
start_url = 'http://www.ip3366.net/?stype=1&page={}'.format(i)
html = get_page(start_url)
if html:
find_tr = re.compile('
(.*?)', re.S)trs = find_tr.findall(html)
for s in range(1, len(trs)):
find_ip = re.compile('
(\d+\.\d+\.\d+\.\d+)')re_ip_address = find_ip.findall(trs[s])
find_port = re.compile('
(\d+)')re_port = find_port.findall(trs[s])
for address,port in zip(re_ip_address, re_port):
address_port = address+':'+port
yield address_port.replace(' ','')
def crawl_kuaidaili(self):
for i in range(1, 4):
start_url = 'http://www.kuaidaili.com/free/inha/{}/'.format(i)
html = get_page(start_url)
if html:
ip_address = re.compile('
(.*?)')re_ip_address = ip_address.findall(html)
port = re.compile('
(.*?)')re_port = port.findall(html)
for address,port in zip(re_ip_address, re_port):
address_port = address+':'+port
yield address_port.replace(' ','')
定義了一個(gè) ProxyMetaclass,Crawl 類將它設(shè)置為元類,元類中實(shí)現(xiàn)了 new() 方法,遍歷 attrs 變量即可獲取類的所有方法信息,判斷方法名前面是否是 crawl,是則將其加入到 CrawlFunc 屬性中
代理網(wǎng)站的添加非常靈活,不僅可以添加免費(fèi)代理,也可以添加付費(fèi)代理,一些付費(fèi)代理的提取方式類似,也通過(guò) Web 的形式獲取再進(jìn)行解析,解析方式可能更加簡(jiǎn)單,如解析純文本或 Json,解析之后以同樣的方式返回,可以自行擴(kuò)展
utils.py
import requests
from requests.exceptions import ConnectionError
base_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
'Accept-Encoding': 'gzip, deflate, sdch',
'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7'
}
def get_page(url, options={}):
headers = dict(base_headers, **options)
print('正在抓取', url)
try:
response = requests.get(url, headers=headers)
print('抓取成功', url, response.status_code)
if response.status_code == 200:
return response.text
except ConnectionError:
print('抓取失敗', url)
return None
抓取網(wǎng)頁(yè)內(nèi)容的方法,訪問(wèn)鏈接成功后返回整個(gè)網(wǎng)頁(yè) HTML 內(nèi)容,便于后續(xù)對(duì)網(wǎng)頁(yè)具體內(nèi)容的提取。封裝成一個(gè)方法,讓上面的 crawler 在抓取各個(gè)網(wǎng)站時(shí)調(diào)用
進(jìn)行抓取
getter.py
from crawler import Crawler
from setting import *
import sys
class Getter():
def __init__(self):
self.crawler = Crawler()
def run(self):
print('獲取器開(kāi)始執(zhí)行')
for callback_label in range(self.crawler.__CrawlFuncCount__):
callback = self.crawler.__CrawlFunc__[callback_label]
# 獲取代理
all_ip = self.crawler.get_proxies(callback)
if __name__ == '__main__':
get = Getter()
get.run()
運(yùn)行結(jié)果:
網(wǎng)站上的免費(fèi) IP 就被成功抓取下來(lái)了,至于能不能用,就有待驗(yàn)證了
整個(gè)過(guò)程其實(shí)就是一個(gè)普通的爬蟲(chóng),而且沒(méi)什么反爬措施,能到用代理 IP 的地步,代碼里面的訪問(wèn)、抓取部分的細(xì)節(jié)應(yīng)該都看得懂
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的获得代理ippython_Python搭建代理IP池实现获取IP的方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux需要的GLIBCXX版本,li
- 下一篇: pythonwebview自动化测试_G