[python]爬代理ip v2.0(未完待續)


爬代理ip

所有的代碼都放到了我的github上面,

HTTP代理常識

HTTP代理按匿名度可分為透明代理、匿名代理和高度匿名代理。

特別感謝:勤奮的小孩 在評論中指出我文章中的錯誤。

REMOTE_ADDR
HTTP_VIA
HTTP_X_FORWARDED_FOR
你寫的這三個,第一個是網絡層的信息,不屬於HTTP的頭部,后兩個在HTTP頭部的名稱也是不含“HTTP_”的

wiki中關於代理的解釋也出現了這個錯誤:

因為我掛的代理,無法修改wiki上的這個錯誤,希望可以修改的同學可以編輯修改之,方便以后查閱的同學。

代理請求的示例,參考

GET / HTTP/1.1
Host: [scrubbed server host]:8080
Connection: keep-alive
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-ms-application, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-ms-xbap, */*
Accept-Language: ru
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506)
X-Forwarded-For: [scrubbed client's real IP address]
Via: 1.1 proxy11 (NetCache NetApp/5.6.1D24)

1.使用透明代理,對方服務器可以知道你使用了代理,並且也知道你的真實IP。
透明代理訪問對方服務器所帶的HTTP頭信息如下:

VIA = 代理服務器IP
X_FORWARDED_FOR = 你的真實IP

透明代理還是將你的真實IP發送給了對方服務器,因此無法達到隱藏身份的目的。

2.使用匿名代理,對方服務器可以知道你使用了代理,但不知道你的真實IP。
匿名代理訪問對方服務器所帶的HTTP頭信息如下:

VIA = 代理服務器IP
X_FORWARDED_FOR = 代理服務器IP

匿名代理隱藏了你的真實IP,但是向訪問對象透露了你是使用代理服務器訪問他們的。

3.使用高匿名代理,對方服務器不知道你使用了代理,更不知道你的真實IP。
高匿名代理訪問對方服務器所帶的HTTP頭信息如下:

VIA 不顯示
X_FORWARDED_FOR 不顯示

高匿名代理隱藏了你的真實IP,同時訪問對象也不知道你使用了代理,因此隱蔽度最高。

概述

起因:我這次是准備爬取‘高匿的ip’,做一個ip庫,方便后面的爬蟲。這是因為,很多網站或者api接口,都設置了‘訪問間隔時間’(一個ip有訪問次數的限制,超過次數就需要進入‘冷卻CD’)。所以,用我的真實ip,無法高效、快速的爬取內容。

因為工作中使用tornado框架,它帶一個很好用的HTTPClient的庫,所以這次我就直接用它來完成,爬代理ip的工作。我寫了一個Spider類,用於爬url的內容。Content用於存儲內容。

class Spider(object):
    """
    爬取
    """
    def __init__(self, url, **kwargs):
		# 實例化HTTPRequest對象,用於偽造瀏覽器的請求
        self.request = HTTPRequest(url, **dict(CLIENT_CONFIG, **kwargs))

    def get(self, **kwargs):
        return HTTPClient().fetch(self.request, **kwargs)

    def post(self):
        self.request.method = 'POST'
        return HTTPClient().fetch(self.request)


class Content(object):
    """
    存儲內容到數據庫
    """
    def __init__(self):
        self.url = None
        self.content = None

    def get_content(self, url, content):
        self.url = url
        self.content = content

    def save(self):
        create_time = datetime.datetime.now()
        data = models.Data(url=self.url, content=self.content, create_time=create_time)
        data.insert()

爬目標網站

目標網站:國內高匿代理ip,在爬蟲v1.0中,當時爬的太順利了,直接爬就行了,根本不用設置HTTP頭。

1. 所以在爬這次的目標網站的時候,就遇到了錯誤。最后,因為需要設置頭為長連接,否則會返回Timeout。所以爬蟲v2.0,我就建立了一個配置文件,里面設置好了相關的頭信息。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
#   Author  :   XueWeiHan
#   E-mail  :   595666367@qq.com
#   Date    :   16/4/22 下午6:39
#   Desc    :   客戶端請求的常用數據

CLIENT_CONFIG = {
    'headers': {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2)'
                              ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/'
                              '49.0.2623.110 Safari/537.36',
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0'
                          '.9,image/webp,*/*;q=0.8',
                'Accept-Encoding': 'gzip, deflate, sdch',
                'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6',
                'Cache-Control': 'max-age=0',
				'Connection': 'keep-alive'
                }
}

2. 目前為止,爬蟲的配置已經做好了,下面就是具體的爬取內容的邏輯了。代碼如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
#   Author  :   XueWeiHan
#   E-mail  :   595666367@qq.com
#   Date    :   16/4/23 上午10:40
#   Desc    :   獲取ip

from spider import Spider, Content

s = Spider('http://www.xicidaili.com/nn/')
print s.get().code  # 輸出為:200
# 表示成功獲取到url內容,下面開始分析內容,提取內容

3. 接下來和爬蟲v1.0一樣,分析網站的內容,這次我是使用的'BeautifulSoup'庫。使用這個庫,就相當於js中的jquery。使用它的選擇器,獲取頁面元素變的便利BeautifulSoup官方文檔

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
#   Author  :   XueWeiHan
#   E-mail  :   595666367@qq.com
#   Date    :   16/4/23 上午10:40
#   Desc    :   獲取代理ips
from bs4 import BeautifulSoup

from spider import Spider


def get_ip_info(html_response):
    """ 清理內容得到IP信息 """
    ips_list = []
    soup = BeautifulSoup(html_response.body, "html.parser")
    ip_list_table = soup.find(id='ip_list')
    for ip_info in ip_list_table.find_all('tr'):
        ip_detail = ip_info.find_all('td')
        if ip_detail:
            ips_list.append(dict(ip=list(ip_detail)[2].string,
                                 port=list(ip_detail)[3].string))
    return ips_list

s = Spider('http://www.xicidaili.com/nn/')
response = s.get()
ips = get_ip_info(response)
import pprint
pprint.pprint(ips)
#輸出如下:
[{'ip': u'110.73.1.204', 'port': u'8123'},
 {'ip': u'171.39.0.98', 'port': u'8123'},
 ....
 {'ip': u'113.85.116.223', 'port': u'9999'}]

4. ip都已經獲取到了,下面就是把它存起來了。我修改了Content類,提供了存到文件中的方法。代碼如下:

class Content(object):
    """
    存儲內容到數據庫
    """
    def __init__(self, model=None):
        self.model = model

    def save(self, kwargs):
        if self.model:
            data = self.model(**kwargs)
            data.insert()
        else:
            print 'no model'

    @staticmethod
    def save_to_file(all_content, str_split=':', path='./data.txt'):
        """
        把數據存到文件中
        :param all_content: 需要是list類型
        :param str_split: 分割符號
        :param path: 文件位置,默認為當前腳本運行的位置,文件名:data.txt
        """
        with open(path, 'w') as fb:
            print '開始寫入文件'
            for content in all_content:
                content_str = ''
                for k, v in content.items():
                    content_str += v + str_split
                fb.write(content_str+'\n')
            print '寫入文件完成'

TODO

未完待續,電腦要沒電了,還沒帶電源。。。。


免責聲明!

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



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