iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 23
3

嗨,昨天說明了如何爬取動態的網站,今天來介紹HTTP代理也就是HTTP proxy,至於為什麼要使用代理呢?有些網站可能會識別Internet Protocol (IP) address並且封鎖你的IP位址,有一解決方法就是使用網路代理IP!什麼是代理(Proxy)?

是一種特殊的網路服務,允許一個網路終端(一般為用戶端)通過這個服務與另一個網路終端(一般為伺服器)進行非直接的連接。

代理伺服器有以下功能:

  • 提高存取速度
  • 控制對內部資源的存取
  • 過濾內容
  • 隱藏真實IP
  • 突破自身IP存取限制
  • 突破內容過濾機制限制

如上面提到的,Proxy能夠隱藏你的IP,也就是網頁端只會看到代理IP位址而不是你真實IP,而當我們在爬取網站的時候遇到網路速度太慢,可以用代理加強爬取速度,當我們爬取過快被發現是爬蟲程式時,IP可能會被封鎖的時候使用代理ip則可以避免。

現在有很多免費的代理伺服器可以使用,例如 US Proxy List - Free Proxy List(如下圖):
Imgur

從圖中可以看出該網站提供了大量的免費代理伺服器資訊,這時候我們先撰寫爬蟲爬取上面的IP再把這些IP拿來用,不過並不是每組都可以使用,還需要驗證。現在我們就來爬取上面的網站吧!

  • 建立專案與Spider
scrapy startproject get_proxy
cd get_proxy
scrapy genspider proxy_example www.us-proxy.org

開啟spider/proxy_example.py,可以看到:

  • 記得import BeautifulSoup & json
import scrapy
from bs4 import BeautifulSoup
import json
class ProxyExampleSpider(scrapy.Spider):
    name = "proxy_example"
    allowed_domains = ["www.us-proxy.org"]
    start_urls = ['http://www.us-proxy.org']

    def parse(self, response):
        pass

我們就來檢查網頁內容:

Imgur

  • 可以發現它的資料都被包在<tr>內:
def parse(self, response):
    soup = BeautifulSoup(response.text, 'lxml')
    trs = soup.select("#proxylisttable tr")
    for tr in trs:
        tds = tr.select("td")
        if len(tds) > 6:
            print(tds)

Imgur

可以看到每個陣列內容像是:
[<td>69.132.115.163</td>, <td>34494</td>, <td>US</td>, <td class="hm">United States</td>, <td>elite proxy</td>, <td class="hm">no</td>, <td class="hx">yes</td>, <td class="hm">4 hours 31 minutes ago</td>],會發現每個Index都為不同的內容,所以我們可以繼續撰寫程式碼:

def parse(self, response):
    soup = BeautifulSoup(response.text, 'lxml')
    trs = soup.select("#proxylisttable tr")
    for tr in trs:
        tds = tr.select("td")
        if len(tds) > 6:
            ip = tds[0].text
            port = tds[1].text
            anonymity = tds[4].text
            ifScheme = tds[6].text
            if ifScheme == 'yes': 
                scheme = 'https'
            else: scheme = 'http'
            proxy = "%s://%s:%s"%(scheme, ip, port)
  • tds0Index為ip

  • tds1Index為port

  • tds4Index為anonymity

  • tds6Index為httphttps

  • 好了之後我們可以定義meta變數:

meta = {
        'port': port,
        'proxy': proxy,
        'dont_retry': True,
        'download_timeout': 3,
        '_proxy_scheme': scheme,
        '_proxy_ip': ip
      }
print(meta) 

Imgur

這樣就表示都有爬到了,但並不是爬到的內容都可以用,必須要經過驗證,我們可以透過 httpbin驗證。

def parse(self, response):最底下新增:

yield scrapy.Request('https://httpbin.org/ip', callback=self.proxy_check_available, meta=meta, dont_filter=True)

當我們連httpbin,若可以執行則可以得到response:

{
  "origin": "your ip"
}

透過response中的origin可以判斷代理是否匿名的,若相同則表示是成功的匿名:

def proxy_check_available(self, response):
    proxy_ip = response.meta['_proxy_ip']
    if proxy_ip == json.loads(response.text)['origin']:
        yield {
            'scheme': response.meta['_proxy_scheme'],
            'proxy': response.meta['proxy'],
            'port': response.meta['port']
        }
  • 好了就可以執行了:
scrapy crawl proxy_example -o proxy.json

Imgur

這樣就完成了代理池的爬取,接著會說明如何在spider內使用這些代理IP。那就明天見啦!


上一篇
[Day 22] 實戰:Scrpay 爬取動態網頁
下一篇
[Day 24] Scrapy 隨機代理實現
系列文
Scrapy爬蟲與資料處理30天筆記30

1 則留言

0
Huiicat
iT邦新手 5 級 ‧ 2019-11-09 12:43:29

請問我驗證後的IP沒有寫入到json,是什麼原因呢?

我要留言

立即登入留言