最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解基于Scrapy的IP代理池搭建

 更新時(shí)間:2020年09月29日 10:43:27   作者:pengjunlee  
這篇文章主要介紹了詳解基于Scrapy的IP代理池搭建,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、為什么要搭建爬蟲代理池

在眾多的網(wǎng)站防爬措施中,有一種是根據(jù)ip的訪問(wèn)頻率進(jìn)行限制,即在某一時(shí)間段內(nèi),當(dāng)某個(gè)ip的訪問(wèn)次數(shù)達(dá)到一定的閥值時(shí),該ip就會(huì)被拉黑、在一段時(shí)間內(nèi)禁止訪問(wèn)。

應(yīng)對(duì)的方法有兩種:

1. 降低爬蟲的爬取頻率,避免IP被限制訪問(wèn),缺點(diǎn)顯而易見(jiàn):會(huì)大大降低爬取的效率。

2. 搭建一個(gè)IP代理池,使用不同的IP輪流進(jìn)行爬取。

二、搭建思路

1、從代理網(wǎng)站(如:西刺代理、快代理、云代理、無(wú)憂代理)爬取代理IP;

2、驗(yàn)證代理IP的可用性(使用代理IP去請(qǐng)求指定URL,根據(jù)響應(yīng)驗(yàn)證代理IP是否生效);

3、將可用的代理IP保存到數(shù)據(jù)庫(kù);

在《Python爬蟲代理池搭建》一文中我們已經(jīng)使用Python的 requests 模塊簡(jiǎn)單實(shí)現(xiàn)了一個(gè)IP代理池搭建,但是爬取速度較慢。由于西刺代理、快代理和云代理等網(wǎng)站需要爬取的IP代理列表頁(yè)多達(dá)上千頁(yè),使用此種方法來(lái)爬取其實(shí)并不適合。

本文將以快代理網(wǎng)站的IP代理爬取為例,示例如何使用 Scrapy-Redis 來(lái)爬取代理IP。

三、搭建代理池

scrapy 項(xiàng)目的目錄結(jié)構(gòu)如下:

items.py

# -*- coding: utf-8 -*-
import re
import scrapy
from proxy_pool.settings import PROXY_URL_FORMATTER

schema_pattern = re.compile(r'http|https$', re.I)
ip_pattern = re.compile(r'^([0-9]{1,3}.){3}[0-9]{1,3}$', re.I)
port_pattern = re.compile(r'^[0-9]{2,5}$', re.I)


class ProxyPoolItem(scrapy.Item):
  # define the fields for your item here like:
  # name = scrapy.Field()
  '''
    {
      "schema": "http", # 代理的類型
      "ip": "127.0.0.1", # 代理的IP地址
      "port": "8050", # 代理的端口號(hào)
      "original":"西刺代理",
      "used_total": 11, # 代理的使用次數(shù)
      "success_times": 5, # 代理請(qǐng)求成功的次數(shù)
      "continuous_failed": 3, # 使用代理發(fā)送請(qǐng)求,連續(xù)失敗的次數(shù)
      "created_time": "2018-05-02" # 代理的爬取時(shí)間
    }
  '''
  schema = scrapy.Field()
  ip = scrapy.Field()
  port = scrapy.Field()
  original = scrapy.Field()
  used_total = scrapy.Field()
  success_times = scrapy.Field()
  continuous_failed = scrapy.Field()
  created_time = scrapy.Field()

  # 檢查IP代理的格式是否正確
  def _check_format(self):
    if self['schema'] is not None and self['ip'] is not None and self['port'] is not None:
      if schema_pattern.match(self['schema']) and ip_pattern.match(self['ip']) and port_pattern.match(
          self['port']):
        return True
    return False

  # 獲取IP代理的url
  def _get_url(self):
    return PROXY_URL_FORMATTER % {'schema': self['schema'], 'ip': self['ip'], 'port': self['port']}

kuai_proxy.py

# -*- coding: utf-8 -*-
import re
import time
import scrapy
from proxy_pool.utils import strip, logger
from proxy_pool.items import ProxyPoolItem


class KuaiProxySpider(scrapy.Spider):
  name = 'kuai_proxy'
  allowed_domains = ['kuaidaili.com']
  start_urls = ['https://www.kuaidaili.com/free/inha/1/', 'https://www.kuaidaili.com/free/intr/1/']

  def parse(self, response):
    logger.info('正在爬取:< ' + response.request.url + ' >')
    tr_list = response.css("div#list>table>tbody tr")
    for tr in tr_list:
      ip = tr.css("td[data-title='IP']::text").get()
      port = tr.css("td[data-title='PORT']::text").get()
      schema = tr.css("td[data-title='類型']::text").get()
      if schema.lower() == "http" or schema.lower() == "https":
        item = ProxyPoolItem()
        item['schema'] = strip(schema).lower()
        item['ip'] = strip(ip)
        item['port'] = strip(port)
        item['original'] = '快代理'
        item['created_time'] = time.strftime('%Y-%m-%d', time.localtime(time.time()))
        if item._check_format():
          yield item
    next_page = response.xpath("http://a[@class='active']/../following-sibling::li/a/@href").get()
    if next_page is not None:
      next_url = 'https://www.kuaidaili.com' + next_page
      yield scrapy.Request(next_url)

middlewares.py

# -*- coding: utf-8 -*-

import random
from proxy_pool.utils import logger


# 隨機(jī)選擇 IP 代理下載器中間件
class RandomProxyMiddleware(object):

  # 從 settings 的 PROXIES 列表中隨機(jī)選擇一個(gè)作為代理
  def process_request(self, request, spider):
    proxy = random.choice(spider.settings['PROXIES'])
    request.meta['proxy'] = proxy
    return None


# 隨機(jī)選擇 User-Agent 的下載器中間件
class RandomUserAgentMiddleware(object):
  def process_request(self, request, spider):
    # 從 settings 的 USER_AGENTS 列表中隨機(jī)選擇一個(gè)作為 User-Agent
    user_agent = random.choice(spider.settings['USER_AGENT_LIST'])
    request.headers['User-Agent'] = user_agent
    return None

  def process_response(self, request, response, spider):
    # 驗(yàn)證 User-Agent 設(shè)置是否生效
    logger.info("headers ::> User-Agent = " + str(request.headers['User-Agent'], encoding="utf8"))
    return response

pipelines.py

# -*- coding: utf-8 -*-

import json
import redis
from proxy_pool.settings import REDIS_HOST,REDIS_PORT,REDIS_PARAMS,PROXIES_UNCHECKED_LIST,PROXIES_UNCHECKED_SET

server = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT,password=REDIS_PARAMS['password'])

class ProxyPoolPipeline(object):

  # 將可用的IP代理添加到代理池隊(duì)列
  def process_item(self, item, spider):
    if not self._is_existed(item):
      server.rpush(PROXIES_UNCHECKED_LIST, json.dumps(dict(item),ensure_ascii=False))

  # 檢查IP代理是否已經(jīng)存在
  def _is_existed(self,item):
    added = server.sadd(PROXIES_UNCHECKED_SET, item._get_url())
    return added == 0

settings.py

# -*- coding: utf-8 -*-
BOT_NAME = 'proxy_pool'

SPIDER_MODULES = ['proxy_pool.spiders']
NEWSPIDER_MODULE = 'proxy_pool.spiders'

# 保存未檢驗(yàn)代理的Redis key
PROXIES_UNCHECKED_LIST = 'proxies:unchecked:list'

# 已經(jīng)存在的未檢驗(yàn)HTTP代理和HTTPS代理集合
PROXIES_UNCHECKED_SET = 'proxies:unchecked:set'

# 代理地址的格式化字符串
PROXY_URL_FORMATTER = '%(schema)s://%(ip)s:%(port)s'

# 通用請(qǐng)求頭字段
DEFAULT_REQUEST_HEADERS = {
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
  'Accept-Encoding': 'gzip, deflate, br',
  'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7',
  'Connection': 'keep-alive'
}

# 請(qǐng)求太頻繁會(huì)導(dǎo)致 503 ,在此設(shè)置 5 秒請(qǐng)求一次
DOWNLOAD_DELAY = 5 # 250 ms of delay

USER_AGENT_LIST = [
  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
  "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
  "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
  "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
  "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
  "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
  "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
  "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
  "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
  "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
  "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
  "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
  "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
  'proxy_pool.middlewares.RandomUserAgentMiddleware': 543,
  #  'proxy_pool.middlewares.RandomProxyMiddleware': 544,
}

ITEM_PIPELINES = {
  'proxy_pool.pipelines.ProxyPoolPipeline': 300,
}

PROXIES = [
  "https://171.13.92.212:9797",
  "https://164.163.234.210:8080",
  "https://143.202.73.219:8080",
  "https://103.75.166.15:8080"
]

######################################################
##############下面是Scrapy-Redis相關(guān)配置################
######################################################

# 指定Redis的主機(jī)名和端口
REDIS_HOST = '172.16.250.238'
REDIS_PORT = 6379
REDIS_PARAMS = {'password': '123456'}

# 調(diào)度器啟用Redis存儲(chǔ)Requests隊(duì)列
SCHEDULER = "scrapy_redis.scheduler.Scheduler"

# 確保所有的爬蟲實(shí)例使用Redis進(jìn)行重復(fù)過(guò)濾
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

# 將Requests隊(duì)列持久化到Redis,可支持暫?;蛑貑⑴老x
SCHEDULER_PERSIST = True

# Requests的調(diào)度策略,默認(rèn)優(yōu)先級(jí)隊(duì)列
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'

utils.py

# -*- coding: utf-8 -*-
import logging

# 設(shè)置日志輸出格式
logging.basicConfig(level=logging.INFO,
          format='[%(asctime)-15s] [%(levelname)8s] [%(name)10s ] - %(message)s (%(filename)s:%(lineno)s)',
          datefmt='%Y-%m-%d %T'
          )
logger = logging.getLogger(__name__)

# Truncate header and tailer blanks
def strip(data):
  if data is not None:
    return data.strip()
  return data

到此這篇關(guān)于詳解基于Scrapy的IP代理池搭建的文章就介紹到這了,更多相關(guān)Scrapy IP代理池搭建內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python通過(guò)四大 AutoEDA 工具包快速產(chǎn)出完美數(shù)據(jù)報(bào)告

    Python通過(guò)四大 AutoEDA 工具包快速產(chǎn)出完美數(shù)據(jù)報(bào)告

    在三年前,我們做數(shù)據(jù)競(jìng)賽或者數(shù)據(jù)建模類的項(xiàng)目時(shí),前期我們會(huì)耗費(fèi)較多的時(shí)間去分析數(shù)據(jù),但現(xiàn)在非常多擅長(zhǎng)數(shù)據(jù)分析的大師們已經(jīng)將我們平時(shí)??吹臄?shù)據(jù)方式進(jìn)行了集成,開(kāi)發(fā)了很多AutoEDA的工具包??梢詭椭覀児?jié)省大量時(shí)間
    2021-11-11
  • 分享Pandas庫(kù)中的一些寶藏函數(shù)transform()

    分享Pandas庫(kù)中的一些寶藏函數(shù)transform()

    Pandas具有很多強(qiáng)大的功能,transform就是其中之一,利用它可以高效地匯總數(shù)據(jù)且不改變數(shù)據(jù)行數(shù),transform是一種什么數(shù)據(jù)操作?如果熟悉SQL的窗口函數(shù),就非常容易理解了
    2021-09-09
  • python Qt5實(shí)現(xiàn)窗體跟蹤鼠標(biāo)移動(dòng)

    python Qt5實(shí)現(xiàn)窗體跟蹤鼠標(biāo)移動(dòng)

    今天小編就為大家分享一篇python Qt5實(shí)現(xiàn)窗體跟蹤鼠標(biāo)移動(dòng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • Python曲線平滑的實(shí)現(xiàn)示例

    Python曲線平滑的實(shí)現(xiàn)示例

    本文主要介紹了Python曲線平滑的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Python如何實(shí)現(xiàn)均直方圖均衡化

    Python如何實(shí)現(xiàn)均直方圖均衡化

    這篇文章主要介紹了Python如何實(shí)現(xiàn)均直方圖均衡化問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 深入淺析Python中的yield關(guān)鍵字

    深入淺析Python中的yield關(guān)鍵字

    python中有一個(gè)非常有用的語(yǔ)法叫做生成器,所利用到的關(guān)鍵字就是yield。接下來(lái)腳本之家小編給大家?guī)?lái)了Python中的yield關(guān)鍵字詳細(xì)解析,感興趣的朋友參考下吧
    2018-01-01
  • python實(shí)習(xí)總結(jié)(yeild,async,azwait和協(xié)程)

    python實(shí)習(xí)總結(jié)(yeild,async,azwait和協(xié)程)

    今天是Python實(shí)習(xí)的第一天,熟悉了環(huán)境,第一次使用macbook,氛圍還不錯(cuò),努力學(xué)習(xí)新知識(shí),希望本片文章能給你帶來(lái)幫助
    2021-10-10
  • 如何優(yōu)雅地處理Django中的favicon.ico圖標(biāo)詳解

    如何優(yōu)雅地處理Django中的favicon.ico圖標(biāo)詳解

    默認(rèn)情況下,瀏覽器訪問(wèn)一個(gè)網(wǎng)站的時(shí)候,同時(shí)還會(huì)向服務(wù)器請(qǐng)求"/favicon.ico"這個(gè)URL,目的是獲取網(wǎng)站的圖標(biāo),下面這篇文章主要給大家介紹了關(guān)于如何優(yōu)雅地處理Django中favicon.ico圖標(biāo)的相關(guān)資料,需要的朋友可以參考下
    2018-07-07
  • Python閉包與裝飾器原理及實(shí)例解析

    Python閉包與裝飾器原理及實(shí)例解析

    這篇文章主要介紹了Python閉包與裝飾器原理及實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • springboot配置文件抽離 git管理統(tǒng) 配置中心詳解

    springboot配置文件抽離 git管理統(tǒng) 配置中心詳解

    在本篇文章里小編給大家整理的是關(guān)于springboot配置文件抽離 git管理統(tǒng) 配置中心的相關(guān)知識(shí)點(diǎn)內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。
    2019-09-09

最新評(píng)論

曲麻莱县| 壤塘县| 汝南县| 徐州市| 新野县| 类乌齐县| 黔南| 阿坝| 平安县| 宿州市| 福建省| 宜宾市| 泗洪县| 鹿邑县| 紫金县| 天峻县| 驻马店市| 莱阳市| 金川县| 桐乡市| 南乐县| 德庆县| 石首市| 连南| 山丹县| 留坝县| 台江县| 贵阳市| 湖口县| 巴楚县| 黄大仙区| 崇明县| 石阡县| 绥江县| 孟连| 方山县| 海门市| 泗洪县| 庄河市| 白城市| 芮城县|