欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python搭建代理IP池實(shí)現(xiàn)獲取IP的方法

 更新時(shí)間:2019年10月27日 14:49:34   作者:Steven·簡(jiǎn)談  
這篇文章主要介紹了Python搭建代理IP池實(shí)現(xiàn)獲取IP的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

使用爬蟲時(shí),大部分網(wǎng)站都有一定的反爬措施,有些網(wǎng)站會(huì)限制每個(gè) IP 的訪問速度或訪問次數(shù),超出了它的限制你的 IP 就會(huì)被封掉。對(duì)于訪問速度的處理比較簡(jiǎn)單,只要間隔一段時(shí)間爬取一次就行了,避免頻繁訪問;而對(duì)于訪問次數(shù),就需要使用代理 IP 來幫忙了,使用多個(gè)代理 IP 輪換著去訪問目標(biāo)網(wǎng)址可以有效地解決問題。

目前網(wǎng)上有很多的代理服務(wù)網(wǎng)站提供代理服務(wù),也提供一些免費(fèi)的代理,但可用性較差,如果需求較高可以購(gòu)買付費(fèi)代理,可用性較好。

因此我們可以自己構(gòu)建代理池,從各種代理服務(wù)網(wǎng)站中獲取代理 IP,并檢測(cè)其可用性(使用一個(gè)穩(wěn)定的網(wǎng)址來檢測(cè),最好是自己將要爬取的網(wǎng)站),再保存到數(shù)據(jù)庫(kù)中,需要使用的時(shí)候再調(diào)用。

代碼地址:https://github.com/Stevengz/Proxy_pool

另外三篇:
Python搭建代理IP池(二)- 存儲(chǔ) IP
Python搭建代理IP池(三)- 檢測(cè) IP
Python搭建代理IP池(四)- 接口設(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 開頭,這樣擴(kuò)展的時(shí)候只需要添加 crawl 開頭的方法即可

在這里實(shí)現(xiàn)了幾個(gè)示例,如抓取代理 66、西刺代理、云代理、快代理 四個(gè)免費(fèi)代理網(wǎng)站,這些方法都定義成生成器,通過 yield 返回。首先將網(wǎng)頁獲取,然后用 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('<tr class.*?>(.*?)</tr>', re.S)
    trs = find_trs.findall(html)
    for tr in trs:
     find_ip = re.compile('<td>(\d+\.\d+\.\d+\.\d+)</td>') 
     re_ip_address = find_ip.findall(tr)
     find_port = re.compile('<td>(\d+)</td>')
     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('<tr>(.*?)</tr>', re.S)
    trs = find_tr.findall(html)
    for s in range(1, len(trs)):
     find_ip = re.compile('<td>(\d+\.\d+\.\d+\.\d+)</td>')
     re_ip_address = find_ip.findall(trs[s])
     find_port = re.compile('<td>(\d+)</td>')
     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('<td data-title="IP">(.*?)</td>') 
    re_ip_address = ip_address.findall(html)
    port = re.compile('<td data-title="PORT">(.*?)</td>')
    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)代理的提取方式類似,也通過 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)頁內(nèi)容的方法,訪問鏈接成功后返回整個(gè)網(wǎng)頁 HTML 內(nèi)容,便于后續(xù)對(duì)網(wǎng)頁具體內(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('獲取器開始執(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 就被成功抓取下來了,至于能不能用,就有待驗(yàn)證了

整個(gè)過程其實(shí)就是一個(gè)普通的爬蟲,而且沒什么反爬措施,能到用代理 IP 的地步,代碼里面的訪問、抓取部分的細(xì)節(jié)應(yīng)該都看得懂

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)與算法之雙端隊(duì)列詳解

    Python實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)與算法之雙端隊(duì)列詳解

    這篇文章主要介紹了Python實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)與算法之雙端隊(duì)列,詳細(xì)講述了雙端隊(duì)列的概念、功能、定義及Python實(shí)現(xiàn)與使用雙端隊(duì)列的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • pandas中Series的使用方式

    pandas中Series的使用方式

    這篇文章主要介紹了pandas中Series的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • python從zip中刪除指定后綴文件(推薦)

    python從zip中刪除指定后綴文件(推薦)

    這篇文章給大家介紹了python從zip中刪除指定后綴文件,然后再自動(dòng)壓縮,本文給大家提供了源碼參考,感興趣的朋友跟隨小編一起看看吧
    2019-12-12
  • Pytorch從0實(shí)現(xiàn)Transformer的實(shí)踐

    Pytorch從0實(shí)現(xiàn)Transformer的實(shí)踐

    本文主要介紹了Pytorch從0實(shí)現(xiàn)Transformer的實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Python搭建自己IP代理池的方法實(shí)現(xiàn)

    Python搭建自己IP代理池的方法實(shí)現(xiàn)

    本文主要介紹了Python搭建自己IP代理池的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Python查看已安裝包的版本號(hào)的多種方法

    Python查看已安裝包的版本號(hào)的多種方法

    很多朋友一直使用pip list來查詢,但如果想知道單個(gè),應(yīng)該怎么使用呢,在Python中,可以使用多種方法來查看已安裝包的版本號(hào),本文給大家詳細(xì)介紹了Python查看已安裝包的版本號(hào)的多種方法,需要的朋友可以參考下
    2024-02-02
  • python數(shù)據(jù)可視化的那些操作你了解嗎

    python數(shù)據(jù)可視化的那些操作你了解嗎

    這篇文章主要為大家詳細(xì)介紹了python數(shù)據(jù)可視化操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • python被修飾的函數(shù)消失問題解決(基于wraps函數(shù))

    python被修飾的函數(shù)消失問題解決(基于wraps函數(shù))

    這篇文章主要介紹了python被修飾的函數(shù)消失問題解決(基于wraps函數(shù)),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Python StrEnum基本概念和使用場(chǎng)景分析

    Python StrEnum基本概念和使用場(chǎng)景分析

    StrEnum是Python枚舉家族的一個(gè)強(qiáng)大補(bǔ)充,特別適合處理字符串常量,它結(jié)合了枚舉的類型安全性和字符串的靈活性,使得在許多場(chǎng)景下的編程變得更加簡(jiǎn)潔和安全,本文將介紹StrEnum的基本概念和使用場(chǎng)景,并通過示例代碼來展示它的實(shí)際應(yīng)用,感興趣的朋友跟隨小編一起看看吧
    2024-07-07
  • Python 工具類實(shí)現(xiàn)大文件斷點(diǎn)續(xù)傳功能詳解

    Python 工具類實(shí)現(xiàn)大文件斷點(diǎn)續(xù)傳功能詳解

    用python進(jìn)行大文件下載的時(shí)候,一旦出現(xiàn)網(wǎng)絡(luò)波動(dòng)問題,導(dǎo)致文件下載到一半。如果將下載不完全的文件刪掉,那么又需要從頭開始,如果連續(xù)網(wǎng)絡(luò)波動(dòng),是不是要頭禿了。本文提供斷點(diǎn)續(xù)傳下載工具方法,希望可以幫助到你
    2021-10-10

最新評(píng)論