91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python搭建代理IP池實現存儲IP的示例

發布時間:2021-02-07 14:17:25 來源:億速云 閱讀:225 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關Python搭建代理IP池實現存儲IP的示例的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

存儲的方式有很多,直接一點的可以放在一個文本文件中,但操作起來不太靈活,而我選擇的是 MySQL 數據庫,因為數據庫便于管理而且功能強大,當然你還可以選擇其他數據庫,比如 MongoDBRedis 等。

使用的庫:pymysql

定義規則

數據庫存儲的主要對象是各個 IP,首先需要保證不重復,另外還需要標 IP 的可用情況,而且需要動態實時處理每個 IP,因此還需要定義一個分數字段,分數是可以重復的,最好是整數類型,每個 IP 都有一個分數,表現其可用性

對于代理池來說,分數可以作為我們判斷一個代理可用不可用的標志,我們將設置一個最高分(滿分,值由自己設置),代表可用,0 設為最低分,代表不可用。從代理池中獲取代理的時候會先從滿分 IP 中隨機獲取一個,注意這里是隨機,這樣可以保證每個可用 IP 都會被調用到,如果沒有滿分的就從所有 IP 從隨機選一個

分數規則如下:

  • 滿分為可用,檢測器會定時循環檢測每個 IP 的可用情況,一旦檢測到有可用的 IP 就立即置為滿分,檢測到不可用就將分數減 1,減至 0 后移除。

  • 新獲取的代理添加時將分數置為 10,當測試可行立即置 100,不可行分數減 1,減至 0 后移除

添加設置

先在一個文件中定義一些配置信息,如數據庫的設置、一些不變量如滿分的數值等

setting.py

# 數據庫地址
HOST = '127.0.0.1'
# MySql端口
MYSQL_PORT = 3306
# MySQl用戶名、密碼
MYSQL_USERNAME = '***'
MYSQL_PASSWORD = '***'
# 數據庫名
SQL_NAME = 'test'

# 代理等級
MAX_SCORE = 30
MIN_SCORE = 0
INITIAL_SCORE = 10

# 代理池數量界限
POOL_UPPER_THRESHOLD = 1000

MAX_SCORE、MIN_SCORE、INITIAL_SCORE 分別代表最大分數、最小分數、初始分數

定義方法

定義一個類來操作數據庫的有序集合,內含一些方法來實現分數的設置、代理的獲取等

db.py

import pymysql
from error import PoolEmptyError
from setting import *
from random import choice
import re


class MySqlClient(object):
 # 初始化
 def __init__(self, host=HOST, port=MYSQL_PORT, username=MYSQL_USERNAME, password=MYSQL_PASSWORD, sqlname=SQL_NAME):
  self.db = pymysql.connect(host=host, user=username, password=password, port=port, db=sqlname)
  self.cursor = self.db.cursor()

 # 添加代理IP
 def add(self, ip, score=INITIAL_SCORE):
  sql_add = "INSERT INTO PROXY (IP,SCORE) VALUES ('%s', %s)" % (ip, score)
  if not re.match('\d+\.\d+\.\d+\.\d+\:\d+', ip):
   print('代理不符合規范', ip, '丟棄')
   return
  if not self.exists(ip):
   self.cursor.execute(sql_add)
   self.db.commit()

 # 減少代理分數
 def decrease(self, ip):
  sql_get = "SELECT * FROM PROXY WHERE IP='%s'" % (ip)
  self.cursor.execute(sql_get)
  score = self.cursor.fetchone()[1]
  print(score)
  if score and score > MIN_SCORE:
   print('代理', ip, '當前分數', score, '減1')
   sql_change = "UPDATE PROXY SET SCORE = %s WHERE IP = '%s'" % (score-1, ip)
  else:
   print('代理', ip, '當前分數', score, '移除')
   sql_change = "DELETE FROM PROXY WHERE IP = %s" % (ip)
  self.cursor.execute(sql_change)
  self.db.commit()

 # 分數最大化
 def max(self, ip):
  print('代理', ip, '可用,設置為', MAX_SCORE)
  sql_max = "UPDATE PROXY SET SCORE = %s WHERE IP = '%s'" % (MAX_SCORE, ip)
  self.cursor.execute(sql_max)
  self.db.commit()
  
 # 隨機獲取有效代理
 def random(self):
  # 先從滿分中隨機選一個
  sql_max = "SELECT * FROM PROXY WHERE SCORE=%s" % (MAX_SCORE)
  if self.cursor.execute(sql_max):
   results = self.cursor.fetchall()
   return choice(results)[0]
  # 沒有滿分則隨機選一個
  else:
   sql_all = "SELECT * FROM PROXY WHERE SCORE BETWEEN %s AND %s" % (MIN_SCORE, MAX_SCORE)
   if self.cursor.execute(sql_all):
    results = self.cursor.fetchall()
    return choice(results)[0]
   else:
    raise PoolEmptyError

 # 判斷是否存在
 def exists(self, ip):
  sql_exists = "SELECT 1 FROM PROXY WHERE IP='%s' limit 1" % ip
  return self.cursor.execute(sql_exists)
  
 # 獲取數量
 def count(self):
  sql_count = "SELECT * FROM PROXY"
  return self.cursor.execute(sql_count)

 # 獲取全部
 def all(self):
  self.count()
  return self.cursor.fetchall()

 # 批量獲取
 def batch(self, start, stop):
  sql_batch = "SELECT * FROM PROXY LIMIT %s, %s" % (start, stop - start)
  self.cursor.execute(sql_batch)
  return self.cursor.fetchall()

方法作用:

  • init():初始化的方法,參數是 MySQL 的連接信息,默認的連接信息已經定義為常量,在 init() 方法中初始化建立 MySQL 連接。這樣當 MySqlClient 類初始化的時候就建立了 MySQL 的連接

  • add():向數據庫添加代理并設置分數,默認的分數是 INITIAL_SCORE 也就是 10,返回結果是添加的結果

  • decrease():在 檢測無效的時候設置分數減 1 的方法,傳入代理,然后將此代理的分數減 1,如果達到最低值就刪除

  • max():將代理的分數設置為 MAX_SCORE,也就是當 IP 有效時的設置

  • random():隨機獲取 IP 的方法,首先獲取滿分的 IP,然后隨機選擇一個返回,如果不存在滿分的 IP,則隨機選擇一個返回,否則拋出異常

  • exists():判斷 IP 是否存在于數據庫中

  • count():返回當前 IP個數

  • all():返回所有的 IP,供檢測使用

  • batch():返回數據庫中從第 start 行開始(從0開始數)的共 stop-start 行數據

抓取保存

當數據庫設置好了之后,就可以直接把抓取的 IP 直接放在數據庫中了

直接把前面用到的抓取代碼更改一下就行了

getter.py

from crawler import Crawler
from db import MySqlClient
from setting import *
import sys


class Getter():
 def __init__(self):
  self.mysql = MySqlClient()
  self.crawler = Crawler()

 # 判斷數量是否足夠
 def is_over_threshold(self):
  if self.mysql.count() >= POOL_UPPER_THRESHOLD:
   return True
  else:
   return False
 
 def run(self):
  print('獲取器開始執行')
  if not self.is_over_threshold():
   for callback_label in range(self.crawler.__CrawlFuncCount__):
    callback = self.crawler.__CrawlFunc__[callback_label]
    # 獲取代理
    all_ip = self.crawler.get_proxies(callback)
    sys.stdout.flush()
    for ip in all_ip:
     self.mysql.add(ip)


if __name__ == '__main__':
 get = Getter()
 get.run()

結果:

Python搭建代理IP池實現存儲IP的示例

感謝各位的閱讀!關于“Python搭建代理IP池實現存儲IP的示例”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

庐江县| 杭锦旗| 盘山县| 肇庆市| 闻喜县| 景洪市| 兰西县| 汉寿县| 石河子市| 顺平县| 利川市| 明溪县| 武威市| 永州市| 祁门县| 浦县| 莲花县| 卓尼县| 南安市| 丹江口市| 冀州市| 和林格尔县| 南溪县| 济宁市| 凯里市| 西和县| 海阳市| 潜江市| 杭锦旗| 长海县| 金寨县| 中山市| 鹿邑县| 漳浦县| 普陀区| 阿鲁科尔沁旗| 珲春市| 赤峰市| 阜康市| 襄樊市| 同江市|