11.scrapy之隨機(jī)設(shè)置請(qǐng)求頭和ip代理池中間件

Request和Response都會(huì)首先經(jīng)過中間件,所以我們?cè)谥虚g件中定義需要添加的header和params

scrapy中最重要的的兩個(gè)類Response和Request

from scrapy import Request

class Request(object_ref):

    def __init__(self, url, callback=None, method='GET', headers=None, body=None,
                 cookies=None, meta=None, encoding='utf-8', priority=0,
                 dont_filter=False, errback=None, flags=None):

request是由spider產(chǎn)生

User-Agent

1.我們可以通過下述方式添加header

class ZhihuSpider(scrapy.Spider):
    name = "zhihu"
    allowed_domains = ["www.zhihu.com"]
    start_urls = ['https://www.zhihu.com/']

    headers = {
        "HOST": "www.zhihu.com",
        "Referer": "https://www.zhizhu.com",
        'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0"
    }

    def parse(self, response):
        ........
                yield scrapy.Request(url, headers=self.headers, callback=self.parse)

2.隨機(jī)添加User-Agent
我們可以提前準(zhǔn)備user-agent的列表报咳,這樣request的時(shí)候隨機(jī)抽取放到header中去椎咧。不過python中有現(xiàn)成的庫已經(jīng)幫我們完成了這個(gè)任務(wù)
https://github.com/hellysmile/fake-useragent

pip install fake-useragent

from fake_useragent import UserAgent
ua = UserAgent()
ua.random

我們?cè)趍iddleware中定義隨機(jī)請(qǐng)求頭玖详,畢竟request要經(jīng)過中間件才發(fā)送出去

# pipeline.py
from fake_useragent import UserAgent
class RandomUserAgentMiddleware(object):
    def __init__(self, crawler):
        super(RandomUserAgentMiddleware, self).__init__()

        self.ua = UserAgent()
        self.per_proxy = crawler.settings.get('RANDOM_UA_PER_PROXY', False)
        self.ua_type = crawler.settings.get('RANDOM_UA_TYPE', 'random')
        self.proxy2ua = {}

    @classmethod
    def from_crawler(cls, crawler):
        return cls(crawler)

    def process_request(self, request, spider):
        def get_ua():
            '''Gets random UA based on the type setting (random, firefox…)'''
            return getattr(self.ua, self.ua_type)

        if self.per_proxy:
            proxy = request.meta.get('proxy')
            if proxy not in self.proxy2ua:
                self.proxy2ua[proxy] = get_ua()
                logger.debug('Assign User-Agent %s to Proxy %s'
                             % (self.proxy2ua[proxy], proxy))
            request.headers.setdefault('User-Agent', self.proxy2ua[proxy])
        else:
            ua = get_ua()
            request.headers.setdefault('User-Agent', get_ua())

IP代理

ip代理是通過request的meta屬性進(jìn)行傳入

    def process_request(self,request,spider):
        get_ip = GetIP()  #自己定義獲取proxy ip函數(shù)
        request.meta["proxy"] = get_ip

1.自己定義爬蟲抓取西刺網(wǎng)上的代理ip,存放到數(shù)據(jù)庫中使用
2.pip install scrapy-proxies
https://github.com/aivarsk/scrapy-proxies

以下是爬取西刺網(wǎng)的免費(fèi)代理ip代碼:

import requests
from bs4 import BeautifulSoup
import pymysql

conn = pymysql.connect(
    host='127.0.0.1',
    user='root',
    password='123456',
    database='xiciip',
    port=3306
)
cursor = conn.cursor()

def crawl_ips():
    #爬取西刺網(wǎng)代理ip
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36"
    }
    for i in range(1,100):
        print("==================",i)
        re = requests.get("http://www.xicidaili.com/nn/{0}".format(i),headers=headers)
        text = re.text
        soup = BeautifulSoup(text)
        tr_list = soup.select("tr")
        tr_list = tr_list[1:]
        for td_list in tr_list:
            td_ip = td_list.select("td")[1].get_text()
            td_port = td_list.select("td")[2].get_text()
            http_type = td_list.select("td")[5].get_text()
            speed = float((td_list.select("td")[6].div.get('title'))[:-1])
            if speed > 1:
                continue
            insert_sql = """insert into iplist(http_type,ip,port,speed) values(%s,%s,%s,%s)"""
            cursor.execute(insert_sql,((http_type,td_ip,td_port,speed)))
            conn.commit()
            print(td_ip)
    conn.close()


class GetIP(object):
    def delete_ip(self,ip):
        #從數(shù)據(jù)庫中刪除無效的ip
        delete_sql = """delete from iplist where ip=%s"""
        cursor.execute(delete_sql,(ip))
        conn.commit()
        return True

    def judge_ip(self,http_type,ip,port):
        #判斷ip是否可用
        http_url = "http://www.baidu.com"
        proxy_url = "{0}://{1}:{1}".format(http_type,ip,port)
        try:
            proxy = {'http_type': ip+":"+port}
            response = requests.get(http_url,proxies=proxy)
        except Exception as e:
            print("Invalid ip and port")
            self.delete_ip(ip)
            return False
        else:
            code = response.status_code
            if code >= 200 and code < 300:
                print('effective ip')
                return True
            else:
                print("Invalid ip and port")
                self.delete_ip(ip)
                return False

    def get_random_ip(self):
        #從數(shù)據(jù)庫隨機(jī)取一個(gè)可用ip
        random_sql = """
        select http_type,ip,port from iplist order by rand() limit 1
        """
        result = cursor.execute(random_sql)
        for ip_info in cursor.fetchall():
            http_type = ip_info[0]
            ip = ip_info[1]
            port = ip_info[2]

            judge_re = self.judge_ip(http_type,ip,port)
            if judge_re:
                return http_type+"://"+ip+":"+port
            else:
                return self.get_random_ip()

if __name__ == "__main__":
    crawl_ips()
# getip = GetIP()
# print(getip.get_random_ip())
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末勤讽,一起剝皮案震驚了整個(gè)濱河市竹宋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌地技,老刑警劉巖蜈七,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異莫矗,居然都是意外死亡飒硅,警方通過查閱死者的電腦和手機(jī)砂缩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來三娩,“玉大人庵芭,你說我怎么就攤上這事∪讣啵” “怎么了双吆?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長会前。 經(jīng)常有香客問我好乐,道長,這世上最難降的妖魔是什么瓦宜? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任蔚万,我火速辦了婚禮,結(jié)果婚禮上临庇,老公的妹妹穿的比我還像新娘反璃。我一直安慰自己,他們只是感情好假夺,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布淮蜈。 她就那樣靜靜地躺著,像睡著了一般已卷。 火紅的嫁衣襯著肌膚如雪礁芦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天悼尾,我揣著相機(jī)與錄音柿扣,去河邊找鬼。 笑死闺魏,一個(gè)胖子當(dāng)著我的面吹牛未状,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播析桥,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼司草,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了泡仗?” 一聲冷哼從身側(cè)響起埋虹,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎娩怎,沒想到半個(gè)月后搔课,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡截亦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年爬泥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了柬讨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡袍啡,死狀恐怖踩官,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情境输,我是刑警寧澤蔗牡,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站嗅剖,受9級(jí)特大地震影響辩越,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜窗悯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一区匣、第九天 我趴在偏房一處隱蔽的房頂上張望偷拔。 院中可真熱鬧蒋院,春花似錦、人聲如沸莲绰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛤签。三九已至辞友,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間震肮,已是汗流浹背称龙。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留戳晌,地道東北人鲫尊。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像沦偎,于是被迫代替她去往敵國和親疫向。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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