高用代理(爬蟲部分)


  1. 爬蟲部分
  2. 代理檢測
  3. 存儲

爬蟲部分

由于我們的代理有限锅睛,所以需要去一些代理網(wǎng)站上爬取一些可用的高效的代理历谍,所以就需要爬蟲去完成這部分的工作。

為了爬取高效的代理望侈,找到以下的代理網(wǎng)站進行爬取:

  • http://ip.kxdaili.com/
  • http://www.xicidaili.com/
  • http://www.66ip.cn/
  • http://www.66ip.cn/areaindex_%s/1.html
  • http://www.89ip.cn/

首先侥猬,定義個爬蟲類捐韩,我們只需傳入爬取網(wǎng)站的url、正則表達式瞧预、以及標志符flag就可以調(diào)用get_data()函數(shù)進行爬取,大大優(yōu)化了代碼結(jié)構(gòu)垢油,代碼如下:

class Crawler(object):
    def __init__(self, url, regular, flag=None):
        self.url = url
        self.regular = regular
        self.flag = flag

    def get_data(self):
        proxies_list = []
        for i in self.url:
            print(i)
            try:
                text = requests.get(i, headers=config.HEADERS)
            except:
                pass
            time.sleep(5)
            text.encoding = 'utf-8'
            data = re.findall(self.regular, text.text)
            if i[11:15] == '66ip':
                for t in range(1, int(len(data) / self.flag)):
                    proxies = '{}:{}'.format(data[self.flag * t], data[(self.flag * t) + 1])
                    proxies_list.append(proxies)
            elif i[11:15] == '89ip':
                proxies_list = data[1:]
            else:
                for t in range(0, int(len(data) / self.flag)):
                    proxies = '{}:{}'.format(data[self.flag * t], data[(self.flag * t) + 1])
                    proxies_list.append(proxies)
        return proxies_list

代理列表如下:

SPIDER_PARSER_LIST =[
{    # 開心代理
    'url':['http://ip.kxdaili.com/ipList/%s.html#ip' % i for i in range(1, 11)],
    'regular':'<td>(.*?)</td>',
    'flag':7
},
{    # 西刺代理
    'url':['http://www.xicidaili.com/nn/%s' % i for i in range(1, 5)],
    'regular':'<td>(.*?)</td>',
    'flag':5
},
{    # 66ip代理-全國代理
    'url': ['http://www.66ip.cn/%s.html' % i for i in range(1, 40)],
    'regular': '<td>(.*?)</td>',
    'flag':5
},
{    # 66ip代理-各省代理
    'url': ['http://www.66ip.cn/areaindex_%s/1.html' % i for i in range(1, 35)],
    'regular': '<td>(.*?)</td>',
    'flag':5
},
{    # 根據(jù)api獲得代理
    'url': ['http://www.89ip.cn/tqdl.html?api=1&num={}&port=&address=&isp='.format(500)],
    'regular': '(.*?)<br>',
    'flag': None
},
]  

調(diào)用方法如下:

def get_object():
    proxise_list = []
    for pirder_paeser in config.SPIDER_PARSER_LIST:
        url = Crawler(url=pirder_paeser.get('url'), regular=pirder_paeser.get('regular'),
                      flag=pirder_paeser.get('flag')).get_data()
        proxise_list.append(url)
    return proxise_list

代理檢測

將存在列表里的代理組成一個新的列表召娜,利用進程池進行快速地檢測惊楼,檢測主要如下:

  1. 代理是否可用秸讹,代理延遲大于3秒即視為不可用檀咙。
  2. http與https代理劃分璃诀。
  3. 高匿性檢測(此部分完成的不好)。

由于自己的知識的欠缺棕诵,對于代理方面的知識了解不夠全面凿将,導致對于代理檢測也是跟著自己的想法進行測試,不知道是否合理笛匙,請大家指出。代碼如下:

def check(proxy):
    http_proxy_list = []
    http_proxy_gaoni_list = []
    https_proxy_list = []

    proxy_http_dict = {
        'http': proxy
    }
    proxy_https_dict = {
        'https': proxy
    }
    try:
        http_res = requests.get(config.SPIDER_PUBLIC_URL, proxies=proxy_http_dict, timeout=5,
                                headers=config.HEADERS)
        time.sleep(1)
        if http_res.status_code == 200:
            try:
                dic1 = eval(http_res.text)
                ip = dic1.get('remote_addr')
                if ip == public_network_ip:
                    http_proxy_list.append(proxy)
                    print(http_res.text)
                else:
                    print(http_res.text)
                    http_proxy_gaoni_list.append(proxy)
            except:
                pass
    except Exception as e:
        print(e)
    try:
        https_res = requests.get('https://www.baidu.com/', timeout=5, proxies=proxy_https_dict
                                 , headers=config.HEADERS, verify=False)
        time.sleep(1)
        if https_res.status_code == 200:
            print('https:')
            https_proxy_list.append(proxy)
    except Exception as e:
        print(e)
    print(http_proxy_list, http_proxy_gaoni_list, https_proxy_list)
    return http_proxy_list, http_proxy_gaoni_list, https_proxy_list

存儲

利用python的flask-sqlalchemy模塊進行關系到表的映射。Proxy結(jié)構(gòu)如下:

class Proxy(db.Model):
    __tablename__ = 'proxy_pool'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    proxy = db.Column(db.String(100), nullable=False,unique=False)
    http = db.Column(db.String(100), nullable=False)
    type = db.Column(db.String(100), nullable=False)
    score = db.Column(db.Integer, nullable=False)
    add_time = db.Column(db.DateTime, nullable=False)
    check_time = db.Column(db.DateTime, nullable=False)
    res_time = db.Column(db.Float, nullable=False)

存儲是利用非orm結(jié)構(gòu)進行存儲蠢正,將檢測的結(jié)果一次性存儲省店,縮短了存儲時間有鹿,減小了對數(shù)據(jù)庫的壓力葱跋。代碼如下:

def save(proxy_list1, proxy_list2, proxy_list3):

    if len(proxy_list1) > 0:
        session.execute(Proxy.__table__.insert(), [{'proxy': str(i), 'http': 'http', 'type': '透明', 'score': str(100)
                                                       , 'add_time': datetime.datetime.now(),
                                                    'check_time': datetime.datetime.now()
                                                       , 'res_time': 0.1} for i in proxy_list1])
    else:
        pass
    if len(proxy_list2) > 0:
        session.execute(Proxy.__table__.insert(), [
            {'proxy': str(i), 'http': 'https', 'type': '高匿', 'score': str(100), 'add_time': datetime.datetime.now(),
             'check_time': datetime.datetime.now(), 'res_time': 0.1} for i in proxy_list2])
    else:
        pass
    if len(proxy_list3) > 0:
        session.execute(Proxy.__table__.insert(), [
            {'proxy': str(i), 'http': 'http', 'type': '高匿', 'score': str(100), 'add_time': datetime.datetime.now(),
             'check_time': datetime.datetime.now(), 'res_time': 0.1} for i in proxy_list3])
    else:
        pass
    session.commit()
    session.close()

總結(jié)

第一次,合作完成項目,學習到了許多知識如:

  1. 利用類掂碱,充分利用代碼疼燥,降低耦合度。
  2. 利用進程池縮短檢測時間撬即。
  3. 以及非orm存儲數(shù)據(jù)庫剥槐。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绍刮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子孩革,更是在濱河造成了極大的恐慌锅移,老刑警劉巖非剃,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件券坞,死亡現(xiàn)場離奇詭異肺素,居然都是意外死亡倍靡,警方通過查閱死者的電腦和手機塌西,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門栖忠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人捐川,你說我怎么就攤上這事古沥。” “怎么了盹沈?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵肃晚,是天一觀的道長关串。 經(jīng)常有香客問我悍缠,道長卦绣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮溅漾,結(jié)果婚禮上添履,老公的妹妹穿的比我還像新娘脑又。我一直安慰自己问麸,他們只是感情好,可當我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布严卖。 她就那樣靜靜地躺著,像睡著了一般来颤。 火紅的嫁衣襯著肌膚如雪福铅。 梳的紋絲不亂的頭發(fā)上启具,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天拷沸,我揣著相機與錄音跨扮,去河邊找鬼。 笑死帝嗡,一個胖子當著我的面吹牛哟玷,可吹牛的內(nèi)容都是我干的喉脖。 我是一名探鬼主播抑月,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼题诵!你這毒婦竟也來了挨稿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎祭椰,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钉赁,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡携茂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了带膜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸳谜。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖咐扭,靈堂內(nèi)的尸體忽然破棺而出滑废,到底是詐尸還是另有隱情袜爪,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布妻导,位于F島的核電站怀各,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏瓢对。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一醇疼、第九天 我趴在偏房一處隱蔽的房頂上張望法焰。 院中可真熱鬧秧荆,春花似錦埃仪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至葡缰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泛释,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工该互, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留韭畸,地道東北人蔓搞。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓随橘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親机蔗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容