爬蟲怎麼解決封IP?

目標網站國內,條件苛刻 10秒內5次點擊,即遭封鎖,40分鐘解除
數據時效又極強,1W頁,30分鐘必須爬完
企業用,可付費購買IP(3000左右/月)、找不到有效的IP使用,求各位援手給指個方向 叩謝


誰讓你用一個IP了

我每次爬前,都會先去爬代理網站 抓幾百個代理IP 然後驗證可用的和匿名的
封裝一下 誰用誰知道


在網路爬蟲抓取信息的過程中,如果抓取頻率高過了網站的設置閥值,將會被禁止訪問。通常,網站的反爬蟲機制都是依據IP來標識爬蟲的。


於是在爬蟲的開發者通常需要採取兩種手段來解決這個問題:
1、放慢抓取速度,減小對於目標網站造成的壓力。但是這樣會減少單位時間類的抓取量。
2、第二種方法是通過設置代理IP等手段,突破反爬蟲機制繼續高頻率抓取。但是這樣需要多個穩定的代理IP。

代理IP可以搜索到免費的,但是可能不太穩定,也有收費的,但是不一定划算,也可能不是長久之計。


普通的基於ADSL撥號的解決辦法

通常,在抓取過程中遇到禁止訪問,可以重新進行ADSL撥號,獲取新的IP,從而可以繼續抓取。但是這樣在多網站多線程抓取的時候,如果某一個網站的抓取被禁止了,
同時也影響到了其他網站的抓取,整體來說也會降低抓取速度。

一種可能的解決辦法

同樣也是基於ADSL撥號,不同的是,需要兩台能夠進行ADSL撥號的伺服器,抓取過程中使用這兩台伺服器作為代理。
假設有A、B兩台可以進行ADSL撥號的伺服器。爬蟲程序在C伺服器上運行,使用A作為代理訪問外網,如果在抓取過程中遇到禁止訪問的情況,立即將代理切換為B,然後將A進行重新撥號。如果再遇到禁止訪問就切換為A做代理,B再撥號,如此反覆。如下圖:

使用A為代理,B撥號:

使用B為代理,A撥號


這是一道送分題
需求是10000÷(30×60)=6 (5.55556)每秒6個頁面
5÷10=0.5
6÷0.5 =12
12×(40×60)=28800
所以只需要28800個賬號就可以滿足需求
__________________________________________________

看目標網站監控的是(username,ip)頻率還是(ip)頻率
如果是(username,ip)那麼可以多賬號多ip交叉訪問
如果只是ip,那麼只能多搞點代理ip了


代理ip

或寬頻撥號也是思路

利用爬蟲技術能做到哪些很酷很有趣很有用的事情? - Lorry 的回答 - 知乎

這裡面提到了一些技巧


首先,如果嘗試破解對方網站的防採集措施,繞過防採集措施等方法也是有的,但屬於破解或者黑客的範圍了。這種不應該提倡,也有法律風險。


在尊重對方網站知識產權和遊戲規則的前提下,當然也是有辦法獲取數據的。一般有幾種方式

1. 使用代理IP,在IP被封掉之前或者封掉之後迅速換掉該IP,這種做法主要需要大量穩定的代理IP,代理IP有免費的,可以花點時間去找,但是量不大,而且不穩定,大量穩定的一般需要購買,購買是另一個問題了,淘寶大把就不深入說了。購買之後可以使用一些支持代理的採集軟體,這裡的技巧是循環使用,在一個IP沒有被封之前,就換掉,過一會再換回來。這樣就可以使用相對較少的IP進行大量訪問。

2. 使用VPN,VPN跟帶來作用類似,只是技術上稍有差別。本質是一樣的。

3. 使用有大規模雲採集集群的軟體工具,比如八爪魚,八爪魚雲採集平台目前是全球第一大大數據云採集平台,用戶規模超過50萬,並且是國家高新企業。八爪魚雲採集平台有成千上萬台雲伺服器遍布全球各地,每個雲伺服器都配有獨立IP,並且雲採集集群伺服器定期更換,這就形成了一個巨大的IP資源池,而且使用起來也很簡單,只要在軟體中配置好採集規則,然後點一個按鈕啟動雲採集就可以。八爪魚採集器會將採集任務拆分,形成許多小任務,隨機分配到最多幾百台雲採集伺服器上,這樣就同時在使用數百個IP,下次啟動的時候又會隨機分配一批資源,這樣就相當於隨機使用大量不同的IP訪問。被封的概率就比較低了。並且因為同時在很多伺服器上運行,速度也比一台電腦同時使用一個IP的速度快甚多,並且屬於發射後不管的技術,也就是啟動雲採集之後,任務就在八爪魚提供的雲採集平台上運行,自己的電腦關機都可以,採集完成後,數據會被自動匯總,用戶可以選擇導出到Excel,各種資料庫,其他文件等,還有可以選擇使用API導出到自己定義的任何目標中,八爪魚提供了多種採集速度讓用戶選擇,對應分配不同的雲資源。

以上三種方式,優先推薦使用代理IP,當然八爪魚採集器也支持使用代理IP。或者使用雲採集平台。

當然我看還有人說使用撥號網路,斷網撥號,這種方法很古老,效率很低,重新撥號獲取到跟之前一樣的IP的概率很高。實際使用中效果很差,我就不推薦了。

本質上來講,IP是一種資源,要想短時間獲取大量數據,應對IP限制策略,就是要使用大量的IP資源才可以解決。


按照你的說法,平均2秒訪問一次,即遭封鎖,因此只有降低抓取速度,但是又有總量和時間的限制。有個問題:如果我平均2秒多一點訪問一次,是否可以永遠不被封鎖?對方網站的封鎖策略你是否都摸透?
按照現有條件,假設封鎖條件唯一,那1萬頁,30分鐘,平均一秒種的量是5.56次。
如果不考慮動態調度的話,那你可以設置至少6條線路來完成抓取(更正一下,應該是至少12條線路,時間倉促,計算失誤)。
單線的數據回傳照這個條件看起來,根本沒有壓力,可以在抓完一頁,休息2秒的時間內,完成數據提交。
如果的確是這樣的話,你可以考慮用同事家的電腦,只要開機,運行你的程序即可。適當補貼電費就可以。
如果同事這條路走不通,比較便宜的可以租用阿里雲的機器,很便宜,WIN 1000多一年,Linux便宜的才幾百。(當然我們也遇到過整個雲都被封鎖的情況,畢竟IP段相對固定)
終極解決方案就是拉幾條電信的ADSL線路,光纖和電話線都可以,撥號就用CMD方式就可以了。
1000多1年,光纖10M,電話線4M,自己再買幾台機器放過去就行了。
遠程管理可以用Teamviewer,不需要做埠映射,傻瓜式的,有免費版本可以用。
單位里設置一台伺服器負責將客戶機提交的數據進行回收或寫庫。
以上僅供參考。


這種情況,最簡單的解決方法就是通過並行抓取來實現。曾經做過一個系統,起100+台爬蟲去抓取一個限速為10request/min的很嚴格的網站,10w的網頁抓完也就1個多小時的時間。部署在雲平台上,抓完就自動關閉爬蟲,最後的總成本其實是一樣的。當然,你也可以花時間去研究對方具體的屏蔽規則是怎樣的,但是這種費時費力,而且人家稍微改改規則,你又要重頭再來。所以,綜合起來考慮,暴力並行抓取是成本最低的方案。
現在通用的一些抓取工具,都是單機版的。要做成支持雲平台和並行抓取的情況,還是需要蠻多開發量的,這是切身體會。


第一分析網站的封禁方式很重要。 有些網站看似是封禁IP,但是網站的防作弊手段可能不一樣。 例如我們可以通過偽造X-Forwarded-For來在一定程度上偽造發送者IP。 這招對部分網站非常的有效。

第二, 如果偽造反向代理的方式不管用可以採用直接的代理, 代理資源如何獲取,方式很多,網上免費的代理網站也很多但質量高的不多,即便是付費採購的也需要自己清洗,因為代理IP資源可能也是網站掃描出來的。


第三, 如果有足夠的資源還是自建比較好。 比如結合著眾包的思路來做, 比如採用路由器的方式,可以自己定製路由器,用Python自己寫work領任務就好了。 還有可以採用嵌入式設備例如樹莓派的開發。 這樣有一個好處是設備是天然分散式的,被查封的概率比較小。

第四點, 可以採用雲服務, 目前的雲都要動態IP服務, 可以採購他們的這個資源,直接在Api層面上換當前機器的IP。

----

另外補充一下, 數據生產不易, 爬蟲請遵守君子協定。


現在網站都會有防抓取策略,當然上有政策下有對策。

你這種情況使用高匿名動態代理ip即可做到防封。不是廣告,推薦一個代理網站 http://www.data5u.com ,動態代理很好用,下面我貼上JAVA語言使用IP做爬蟲的源代碼

代碼用到了htmlunit和多線程技術

…………………………………………………………

package com.data5u.test;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.ProxyConfig;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

/**
* 這個DEMO主要為了測試動態代理IP的穩定性
* 也可以作為爬蟲參考項目,如需使用,請自行修改代碼webParseHtml方法
*/
public class TestDynamicIp {
public static List ipList = new ArrayList&<&>();
public static boolean gameOver = false;
public static void main(String[] args) {
long fetchIpSeconds = 5;
int threadNum = 10;
int testTime = 3;
// 請填寫無憂代理IP訂單號,填寫之後才可以提取到IP哦
String order = "一定要把這裡改為單號哦~";
// 你要抓去的目標網址
String targetUrl = "http://2017.ip138.com/ic.asp";
// 是否載入JS,載入JS會導致速度變慢
boolean useJS = false;
// 請求超時時間,單位毫秒,默認5秒
int timeOut = 5000;

if (order == null || "".equals(order)) {
System.err.println("請輸入無憂代理IP動態代理訂單號");
return;
}

System.out.println("############無憂代理動態IP測試開始###############");
System.out.println("***************");
System.out.println("介面返回IP為國內各地區,每次最多返回10個");
System.out.println("提取IP間隔 " + fetchIpSeconds + " 秒 ");
System.out.println("開啟爬蟲線程 " + threadNum);
System.out.println("爬蟲目標網址 " + targetUrl);
System.out.println("測試次數 3 ");
System.out.println("***************
");
TestDynamicIp tester = new TestDynamicIp();
new Thread(tester.new GetIP(fetchIpSeconds * 1000, testTime, order)).start();
for (int i = 0; i &< threadNum; i++) {
tester.new Crawler(100, targetUrl, useJS, timeOut).start();
}
while(!gameOver){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("###############無憂代理動態IP測試結束###############");
System.exit(0);
}

// 抓取目標站,檢測IP
public class Crawler extends Thread{
@Override
public void run() {
while(!gameOver){
webParseHtml(targetUrl);
try {
Thread.sleep(sleepMs);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

long sleepMs = 200;
boolean useJs = false;
String targetUrl = "";
int timeOut = 5000;

public Crawler(long sleepMs, String targetUrl, boolean useJs, int timeOut) {
this.sleepMs = sleepMs;
this.targetUrl = targetUrl;
this.useJs = useJs;
this.timeOut = timeOut;
}
public String webParseHtml(String url) {
String html = "";
BrowserVersion[] versions = {BrowserVersion.INTERNET_EXPLORER_11, BrowserVersion.CHROME, BrowserVersion.FIREFOX_38, BrowserVersion.INTERNET_EXPLORER_8};
WebClient client = new WebClient(versions[(int)(versions.length * Math.random())]);
try {
client.getOptions().setThrowExceptionOnFailingStatusCode(false);
client.getOptions().setJavaScriptEnabled(useJs);
client.getOptions().setCssEnabled(false);
client.getOptions().setThrowExceptionOnScriptError(false);
client.getOptions().setTimeout(timeOut);
client.getOptions().setAppletEnabled(true);
client.getOptions().setGeolocationEnabled(true);
client.getOptions().setRedirectEnabled(true);
// 這行代碼允許訪問HTTPS網站,異常參考http://www.data5u.com/help/article-31.html
client.getOptions().setUseInsecureSSL(true);

String ipport = getAProxy();
if (ipport != null) {
ProxyConfig proxyConfig = new ProxyConfig(ipport.split(":")[0], Integer.parseInt(ipport.split(":")[1]));
client.getOptions().setProxyConfig(proxyConfig);
}else {
System.out.print(".");
return "";
}

HtmlPage page = client.getPage(url);
html = page.asXml();

System.out.println(getName() + " 使用代理 " + ipport + "請求目標網址返回HTML:" + html);

} catch (Exception e) {
return webParseHtml(url);
} finally {
client.close();
}
return html;
}

private String getAProxy() {
if (ipList.size() &> 0) {
String ip = ipList.get((int)(Math.random() * ipList.size()));
return ip ;
}
return null;
}
}

// 定時獲取動態IP
public class GetIP implements Runnable{
long sleepMs = 1000;
int maxTime = 3;
String order = "";

public GetIP(long sleepMs, int maxTime, String order) {
this.sleepMs = sleepMs;
this.maxTime = maxTime;
this.order = order;
}

@Override
public void run() {
long getIpTime = 0;
int time = 1;
while(!gameOver){
if(time &>= 4){
gameOver = true;
break;
}
try {
java.net.URL url = new java.net.URL("http://api.ip.data5u.com/dynamic/get.html?order=" + order + "ttl");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setConnectTimeout(3000);
connection = (HttpURLConnection)url.openConnection();

InputStream raw = connection.getInputStream();
InputStream in = new BufferedInputStream(raw);
byte[] data = new byte[in.available()];
int bytesRead = 0;
int offset = 0;
while(offset &< data.length) {
bytesRead = in.read(data, offset, data.length - offset);
if(bytesRead == -1) {
break;
}
offset += bytesRead;
}
in.close();
raw.close();
String[] res = new String(data, "UTF-8").split("
");
List ipList = new ArrayList&<&>();
for (String ip : res) {
try {
String[] parts = ip.split(",");
if (Integer.parseInt(parts[1]) &> 0) {
ipList.add(parts[0]);
}
} catch (Exception e) {
}
}
if (ipList.size() &> 0) {
TestDynamicIp.ipList = ipList;
System.out.println("第" + ++getIpTime + "次獲取動態IP " + ipList.size() + " 個");
time += 1;
}
} catch (Exception e) {
e.printStackTrace();
System.err.println(">&>&>&>&>&>&>&>&>&>&>&>&>&>獲取IP出錯");
}
try {
Thread.sleep(sleepMs);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

}

………………………………………………


要把愛奇藝的所用評論都抓出來,估計量在4000w條左右


除了分散式慢速抓取,貌似暫時沒有別的辦法了


推薦個很好用的軟體,我也是一直在用的,就是前嗅的ForeSpider軟體,
我是一直用過很多的採集軟體,最後選擇的前嗅的軟體,ForeSpider這款軟體是可視化的操作。簡單配置幾步就可以採集。如果網站比較複雜,這個軟體自帶爬蟲腳本語言,通過寫幾行腳本,就可以採集所有的公開數據。

軟體還自帶免費的資料庫,數據採集直接存入資料庫,也可以導出成excel文件。
如果自己不想配置,前嗅可以配置採集模板,我的模板就是從前嗅購買的。

另外他們公司不光是軟體好用,還有自己的數據分析系統,直接採集完數據後入庫,ForeSpider內部集成了數據挖掘的功能,可以快速進行聚類分類、統計分析等,採集結果入庫後就可以形成分析報表。

最主要的是他採集速度非常快,我之前用八爪魚的軟體,開伺服器采,用了一個月采了100萬條,後來我用ForeSpider。筆記本採的,一天就好幾百萬條。

這些都是我一直用前嗅的經驗心得,你不妨試試。

建議你可以下載一個免費版試一試,免費版不限制功能,沒有到期時間。

在反爬蟲上他們有很好的措施,也支持IP代理,免去了被封號的難題。


爬蟲 ≈ 外掛

外掛之奧義:

像人一樣操作而不被發現

反外掛之奧義:

像人一樣的操作也能將其揪出來

如果說外掛是黑色產業,那麼爬蟲可以算是灰白產業

其實封IP策略是很LOW的反爬手段

而國內的HTTP代理(不論收費還是免費)其性能是相當低下

我項目不用第三方HTTP代理

第三方代理不是你一家用,大家都在用,大家都用的就會有不少爬蟲,很容易被污染(特別是網上採集到的免費代理,很多企業一封就是整個網段封停 or 進入到高強度監控列表),為了高效和穩定,還是要自建HTTP代理,實施代理策略

再加不可描述的策略(這裡可以收費,值得)近乎完美的處理IP流量監控導致的封IP反爬手段

因為高效的反爬手段,未必是監控IP流量策略

前面有答主說過高匿方案,其方案是可以被伺服器發現的,凡是匿名伺服器無腦封殺,請問怎麼解決?


樓主要求是

10000/30*60

任務量是 5p/1s

估算成本3000RMB/月買IP問題不大,也就是30個伺服器

爬蟲目標是2s/1次 10s內5次即封IP

那麼自己計算好30個IP使用完以後的IP更新策略,使用多少次即棄用,生成新的IP,並將其加入代理池即可

樓主可以試著把頁面丟出來 讓我們參考參考看看究竟有多難對付

嘎嘎


目前比較主流得還是使用雲分散式的爬蟲是最好的解決方案,代理IP的穩定性始終是個問題。全國幾十台機器同步一批爬一批URL,限制一下單個的爬取時間不要超過閾值,一點壓力都沒有。


iP問題來到這邊,發現看不懂


訊代理不錯 每天提供免費代理ip


可行的方法是進行用代理池輪詢切換,給代理設置使用時間,可用性,被禁性以及訪問速度,然後進行優先順序排序,切換代理時選擇使用時間最久遠的,可用,訪問速度最快的的代理,用過一次就能更新代理的屬性(使用時間等等),放入代理池。

如何獲取代理?

如果時間緊急的話,花錢買代理,而且花錢買的也只有一小部分可用代理,需要進行不停的可用性檢測。

如果時間很充足的話,可以從各個網站上寫爬蟲收集ip,類似於西刺。


之前爬其他網站也遇到IP被封的情況。

然後自己去訊代理買了一天的代理試了下,發現如果代理的篩選條件比較苛刻的話,其實API返回的代理也比較有限。然後看到它首頁實時更新的免費代理,發現還是挺好的,於是就先把訊代理首頁的免費代理先爬下來,再用爬下來的代理去爬其他網站的東西。

具體代碼見我的Github darrenfantasy/image_crawler 里的 XunFreeProxy 文件夾


解決封IP的問題,基本策略就是兩點:

1. 請求數據時要盡量模仿人的行為,請求間隔不要過短或者設成固定值,這樣很容易被反作弊的策略命中,至少設置一個隨機數作為請求間隔吧;

2. 使用代理IP。百度上搜代理IP有好多網站,大部分都不太可用,最著名的應該是『西刺代理』,但是免費IP的通病是不穩定,可用比例不太高,所以越多越好,最近發現一個新網站,叫『極速IP』,上面的IP可用比例目前看還挺高的,你可以試試。

當然,拿到ip後,如何高效的利用所有的ip多線程或多進程的爬數據也是一個不太簡單的調度問題,可以好好研究


用代理共享上網性質的家庭寬頻


推薦閱讀:

python爬蟲如何斷點繼續抓取?
python教程看完了,還是不會編程?
Python有哪些常見的、好用的爬蟲框架?
如何去尋找網路爬蟲的需求?
Python實現爬蟲代理池?

TAG:Python | 爬蟲計算機網路 |