如何維護一個1000 IP的免費代理池


楔子

好友李博士要買房了, 前幾天應邀幫他抓鏈家的數據分析下房價, 爬到一半遇到了驗證碼.

李博士的想法是每天把鏈家在售的二手房數據都抓一遍, 然后按照時間序列分析. 鏈家線上在交易的二手房數據大概有30000余套, 而一天只有86400秒, 也就是最慢3s也要訪問一個頁面. 測試按照這種頻率, 大概訪問100個頁面就會被封了, 而且封鎖的時間還不短, 至少在12小時左右. 如果想要每天快速的爬一些數據, 必須得搞定驗證碼.

鏈家封鎖是按照IP封禁的, 簡單的添加上cookies並沒有什么效果. 要破解IP封禁, 自然地想法是加上代理就好了. 在公司里代碼各種工具都很成熟, 有現成的代理池可用, 自己要爬些數據的時候發現原來什么都需要自己做. 那就自己做個代理池吧.

方案

三種方法:

需要付費的方法

  • 自己買IP地址,自己做代理池. 可以利用各種雲可以換IP的api(彈性IP),采用幾台實例做出口,如果被封了就換IP, 大概看一下IP的價格的話, 就知道這個實在不太現實, 太貴了理論上這個比上一個便宜, 但是還是很貴.

阿里雲上最便宜的主機(內網主機, 沒有公網IP)大概價格在60元左右, 如果自己做代理池的話, 想要多少並發出口就需要多少台主機. 假如我們需要同時有10個IP出口是可用的, 那么主機的費用就是 600元. 另外一個1Mbps的IP的價格大概是30元左右, IP的價格是300元. 每個月搭建一個代理池就要花費近1000元, 實在是用不起.

而且雲主機廠商的IP地址往往是連續的, 很可能換來換去都在一個C段, 這時候對於直接封禁IP段的網站就無解了.

  • 直接購買代理,這些代理往往是通過一些接近黑產的方式掃描端口得來的,需要驗證才能使用.

購買的代理的價格大概是每天幾塊到幾十塊不等, 不同廠商之家大同小異, 一個月最少也都需要幾百元左右. 不過之前聽同事說這些代理的可用性一般, 拿到的代理還需要自己驗證是否可用, 也就是花了錢還不能爽, 自然沒有了買的欲望.

窮人的方法

這些賣代理的網站往往都提供了一些免費代理在首頁來吸引流量, 少則幾十, 多則幾百, 初步測試了幾個還算能用. 既然直接買來代理也還需要驗證, 那還不如直接抓取他們網站上提供的免費代理了. 驗證后入庫, 用的時候直接選取一個用就好了. 如果代理庫里有1000個左右的可用IP, 那還是能解決不少問題的.

代理的一些基礎知識

某網站的代理列表:

一般來說, http/https代理用的比較多, socks代理似乎很少使用. 其中好多代理服務器只支持http代理. 比如 https://www.baidu.com 就只能使用https代理訪問, 而不能使用http代理. 上圖中給出了這些代理的類型, 然而實際測試發現, 這些類型好多都是不准的. 還有響應時間等數據也和服務器有關, 並不能直接使用上面的數據. 所以我們的思路是只要地址和端口, 其他的數據都自己驗證.

架構設計

存儲

我們把抓到的代理存到mysql中, 具體的表設計如下:

CREATE TABLE `proxy` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `ip` varchar(15) NOT NULL,
  `port` int(10) unsigned NOT NULL DEFAULT '3128',
  `type` smallint(5) unsigned NOT NULL DEFAULT '0',
  `country` varchar(2) DEFAULT NULL,
  `state` varchar(15) DEFAULT NULL,
  `enqueue_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `last_check_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `used_times` int(11) NOT NULL DEFAULT '0',
  `from_url` varchar(1024) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `idx_ip_port` (`ip`,`port`)
) ENGINE=InnoDB AUTO_INCREMENT=103 DEFAULT CHARSET=utf8mb4

抓取和驗證

代理的獲取分為兩個線程, 一個線程使用爬蟲不斷掃描已知的代理的網站, 獲得代理的地址, 驗證后入庫. 另一個線程掃描庫里的代理, 驗證是否依然可用.

接口

代理服務對外主要提供一個接口, get_proxy. 需要使用代理的程序每次調用這個接口獲得一個可用代理使用. 每次盡量選取使用次數最少但是存活時間最長的代理.

實現

之前寫過一個簡單的按照配置文件抓取網頁的小爬蟲(https://github.com/yifeikong/minicrawler). 這下終於派上用場了. 把每個網頁抽取代理的xpath配好, 之后就等着在數據庫看數據就好了 _

使用 django 簡單實現了一個后台, 大概是這樣的:

經過測試, 一般代理的存活時間往往在十幾分鍾左右, 但是這些代理網站的更新時間一般也在十幾分鍾, 而且由於找到了大概幾十個網站, 掃一遍並驗證花費的時間可能在幾個小時左右. 所以維持一個可用代理在1k左右的代理庫是不成問題的.

get_proxy 的接口如下:

后記

  1. 經過測試發現, 國外的代理網站往往量很大, 而且可用率也比較高. 然而由於防火牆的原因, 這些網站以及甚至他們提供的代理在國內是不能訪問的, 不過我的主機在阿里雲香港, 所以也就沒有問題了.

  2. 有不少網站顯然是發現了我們這種抓代理的行為, 他們頁面的IP或者端口是加密的, 而在瀏覽器中js執行過后則是有正確結果的. 也就是簡單地通過抽取是得不到正確結果的. 比如這樣:

比如這里在原始網頁中是沒有代理的IP的, 而是通過js動態生成的.

對於這種網頁怎么操作的, 且聽下回分解: 使用headless chrome抓取動態網頁.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM