2017/4/27 cookies

感覺(jué)距離上次交作業(yè)已經(jīng)很久了...
已經(jīng)落后大家這么多了

思路分析

上次交的作業(yè)雖然能夠爬取到數(shù)據(jù)脖阵,但是和大家的不同力穗,完全偏離主題呀,心好痛
這次作業(yè)的關(guān)鍵點(diǎn)是構(gòu)造表單蔫仙,附帶cookies發(fā)送請(qǐng)求
具體的思路前面的同學(xué)已經(jīng)分析的很詳細(xì)了哀卫,就不作一一的論述了
所以這次作業(yè)的主題是總結(jié)與探討兩個(gè)問(wèn)題

為什么帶cookies可以反ban?

想要解決這個(gè)問(wèn)題,就要弄清楚幾個(gè)概念

cookies(來(lái)自維基百科)
因?yàn)?a target="_blank" rel="nofollow">HTTP協(xié)議是無(wú)狀態(tài)的撬槽,即服務(wù)器不知道用戶上一次做了什么此改,這嚴(yán)重阻礙了交互式Web應(yīng)用程序的實(shí)現(xiàn)。在典型的網(wǎng)上購(gòu)物場(chǎng)景中侄柔,用戶瀏覽了幾個(gè)頁(yè)面共啃,買(mǎi)了一盒餅干和兩飲料。最后結(jié)帳時(shí)暂题,由于HTTP的無(wú)狀態(tài)性移剪,不通過(guò)額外的手段,服務(wù)器并不知道用戶到底買(mǎi)了什么薪者。 所以Cookie就是用來(lái)繞開(kāi)HTTP的無(wú)狀態(tài)性的“額外手段”之一纵苛。服務(wù)器可以設(shè)置或讀取Cookies中包含信息,借此維護(hù)用戶跟服務(wù)器會(huì)話中的狀態(tài)。

從cookies的定義可以看出攻人,cookies也是可以作為一個(gè)驗(yàn)證用戶身份的工具取试,所以可以通過(guò)cookies來(lái)區(qū)別機(jī)器和人,所以有一種反爬的策略怀吻,就是通過(guò)cookies瞬浓,拉勾網(wǎng)的反爬蟲(chóng)機(jī)制就是基于cookies,所以同一個(gè)cookies可以重復(fù)請(qǐng)求蓬坡,而同一個(gè)IP不帶cookies卻是不能重復(fù)請(qǐng)求猿棉,會(huì)封IP,但是拉勾網(wǎng)做的還是不夠屑咳,就是只需要一個(gè)cookies萨赁,如果再?lài)?yán)格一點(diǎn),使cookies所保存的時(shí)間短一點(diǎn)乔宿,也許就需要一個(gè)cookies池了位迂,定期加入cookies,這樣爬取的難度就會(huì)增大很多详瑞,再厲害一點(diǎn)掂林,就是IP和cookes一起識(shí)別。

總結(jié)一下目前所遇到的爬取方式

目前所爬取的網(wǎng)站只有三個(gè)坝橡,還是比較少的
但是我覺(jué)得都挺有收獲和代表性的

以源碼顯示網(wǎng)站

這個(gè)基本的是有多基本呢泻帮?只需要正常的提交請(qǐng)求,就能夠得到網(wǎng)站的源碼计寇,然后選取自己想要的信息锣杂,比如說(shuō)有些教務(wù)網(wǎng)和一些小型的網(wǎng)站

以json等格式顯示的網(wǎng)站

如簡(jiǎn)書(shū)的專(zhuān)題數(shù)據(jù),這類(lèi)的數(shù)據(jù)番宁,我們所獲取的內(nèi)容不是網(wǎng)站的源碼元莫,所獲取的是其返回的json等格式的包,所以獲取信息的關(guān)鍵在于解析這個(gè)包來(lái)得到自己想要的內(nèi)容

Ajax形式網(wǎng)站

首先來(lái)個(gè)科普

維基百科
傳統(tǒng)的Web應(yīng)用允許用戶端填寫(xiě)表單(form)蝶押,當(dāng)提交表單時(shí)就向網(wǎng)頁(yè)服務(wù)器發(fā)送一個(gè)請(qǐng)求踱蠢。服務(wù)器接收并處理傳來(lái)的表單,然后送回一個(gè)新的網(wǎng)頁(yè)棋电,但這個(gè)做法浪費(fèi)了許多帶寬茎截,因?yàn)樵谇昂髢蓚€(gè)頁(yè)面中的大部分HTML碼往往是相同的。由于每次應(yīng)用的溝通都需要向服務(wù)器發(fā)送請(qǐng)求赶盔,應(yīng)用的回應(yīng)時(shí)間依賴(lài)于服務(wù)器的回應(yīng)時(shí)間企锌。這導(dǎo)致了用戶界面的回應(yīng)比本機(jī)應(yīng)用慢得多。
與此不同于未,AJAX應(yīng)用可以僅向服務(wù)器發(fā)送并取回必須的數(shù)據(jù)撕攒,并在客戶端采用JavaScript處理來(lái)自服務(wù)器的回應(yīng)陡鹃。因?yàn)樵诜?wù)器和瀏覽器之間交換的數(shù)據(jù)大量減少(大約只有原來(lái)的5%)

這一類(lèi)的網(wǎng)站有如拉勾網(wǎng),這一類(lèi)網(wǎng)站的特點(diǎn)和上一種有點(diǎn)類(lèi)似打却,但是為什么要分開(kāi)來(lái)說(shuō)呢杉适?因?yàn)樯弦环N情形一般會(huì)和源碼一起結(jié)合出現(xiàn),而Ajax網(wǎng)站柳击,需要用戶構(gòu)造表單猿推,向服務(wù)器要求返回想要的內(nèi)容,而且這一類(lèi)網(wǎng)站捌肴,一般是幾乎所有信息(除了導(dǎo)航欄之類(lèi)的通用信息)外蹬叭,都是通過(guò)json, xml返回的,所以只需要從這個(gè)json包中便能獲取所有數(shù)據(jù)状知。

作業(yè)代碼

spider.py

# -*- coding: utf-8 -*-
import scrapy
from lagou.items import LagouItem
import sys
import re
import requests
import json
from bs4 import BeautifulSoup

#import sys
#reload(sys)
#sys.setdefaultencoding('utf-8')




class LagouSpider(scrapy.Spider):
    name = "lagou"

    cookies = {
        'user_trace_token': '20170314211704-f55f18938db84cfeae95d1efec6d585e',
        'LGUID': '20170314211706-859943f0-08b8-11e7-93e0-5254005c3644',
        'JSESSIONID': 'AA1DE67564F4C20F86F89F3572B706A1',
        'PRE_UTM': '',
        'PRE_HOST': 'www.baidu.com',
        'PRE_SITE': 'https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DuQkzN6ld65B8UHLJeaN2RVwWb3jiAl6AkSQSZRkXpRC%26wd%3D%26eqid%3Df6aa96cc0000dd5e0000000258ff3f34',
        'PRE_LAND': 'https%3A%2F%2Fwww.lagou.com%2F',
        'index_location_city': '%E5%85%A8%E5%9B%BD',
        'Hm_lvt_4233e74dff0ae5bd0a3d81c6ccf756e6': '1491116405,1491116452,1493122880,1493122898',
        'Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6': '1493123186',
        '_ga': 'GA1.2.1412866745.1489497427',
        'LGSID': '20170425202132-b7ea71dc-29b1-11e7-bc70-525400f775ce',
        'LGRID': '20170425202620-6394f6bd-29b2-11e7-bc72-525400f775ce',
        'TG-TRACK-CODE': 'search_code',
        'SEARCH_ID': '63e7755cfbbf40559a5dac6a35e5f49f'
    }

    def start_requests(self):
        kds = ['python工程師', 'python數(shù)據(jù)分析']
        citys = ['北京', '上海', '深圳', '廣州', '杭州', '成都', '南京', '武漢', '西安', '廈門(mén)', '長(zhǎng)沙', '蘇州', '天津']
        


        #soup = BeautifulSoup(response.text, 'lxml')
        #pages = soup.find('span', {'class': 'span totalNum'}).get_text()
        
        base_url = "https://www.lagou.com/jobs/positionAjax.json?city="
        for city in citys:
            city_urls = base_url + city + "&needAddtionalResult=false"
            for kd in kds:
                url = "https://www.lagou.com/jobs/list_{}?px=default&city={}#filterBox".format(city, kd)
                r = requests.get(url, cookies=self.cookies)
                soup = BeautifulSoup(r.text, 'lxml')
                pages = soup.find('span', {'class': 'span totalNum'}).get_text()
                for i in range(1, int(pages)+1):
                    formdata = {"first":"ture", "pn": str(i), "kd": kd}
                    yield scrapy.FormRequest(city_urls, formdata=formdata, cookies=self.cookies, callback=self.parse)


    def parse(self, response):

        data = json.loads(response.text)

        item = LagouItem()
        da = data['content']
        a = da['positionResult']
        n = a['result']
        for one in n:
            city = one["city"]
            companyname = one["companyFullName"]
            #companysize = one["companySize"]
            district = one["district"]
            education = one["education"]
            jobNature = one["jobNature"]
            
            try:
                positionLables = ""
                Lables = one["positionLables"]
                for i in Lables:
                    positionLables += i
                item["positionLables"] = positionLables
            except:
                item["positionLables"] = u""

            try:
                positionName = one["positionName"]
                item["positionName"] = positionName
            except:
                item["positionName"] = u""
                
            salary = one["salary"]
            workYear = one["workYear"]

            
            item["city"] = city
            item["companyFullName"] = companyname
            #item["companySize"] = companysize
            item["district"] = district
            item["education"] = education
            item["jobNature"] = jobNature
            #item["positionLables"] = positionLables
            item["salary"] = salary
            item["workYear"] = workYear


        yield item

item.py

import scrapy
class LagouItem(scrapy.Item):
    positionName = scrapy.Field()
    city = scrapy.Field()
    companyFullName = scrapy.Field()
    district = scrapy.Field()
    education = scrapy.Field()
    jobNature = scrapy.Field()
    positionLables = scrapy.Field()
    salary = scrapy.Field()
    workYear = scrapy.Field()

pipelines.py修改下秽五,請(qǐng)教了下程老哥,先試著理解下

import MySQLdb


def dbHandle():
    conn = MySQLdb.connect(
        host = "127.0.0.1",
        user = "root",
        passwd = "882645",
        charset = "utf8",
        db = "Lagou",
        use_unicode = False
    )

    return conn
#連接數(shù)據(jù)庫(kù)饥悴,所需要配置一下數(shù)據(jù)庫(kù)的基本信息

class LagouPipeline(object):
    def process_item(self, item, spider):
        dbObject = dbHandle()
        cursor = dbObject.cursor()
#調(diào)用上面所編寫(xiě)的函數(shù)坦喘,還有其中的一個(gè)方法cursor,用于提交
        sql = "insert into lagou.jobs(positionName,city,companyFullName,district,education,jobNature,positionLables,salary,workYear ) values(%s,%s,%s,%s,%s,%s,%s,%s,%s)"
      #編寫(xiě)插入數(shù)據(jù)庫(kù)的語(yǔ)句
        try:
            cursor.execute(sql,
                           (item['positionName'], item['city'], item['companyFullName'], item['district'], item['education'], item['jobNature'],
             item['positionLables'], item['salary'], item['workYear']))
      #連接item
            cursor.connection.commit()
      #提交item
        except BaseException as e:
            print u"錯(cuò)誤在這里>>>>", e, u"<<<<錯(cuò)誤在這里"
        return item

作業(yè)結(jié)果展示

結(jié)果展示

作業(yè)中遇到的問(wèn)題

這次所選用的是scrapy + mysql
問(wèn)題一:
為什么用scrapy呢西设?本來(lái)是打算寫(xiě)一個(gè)不是框架版的爬蟲(chóng)的瓣铣,但是問(wèn)題就卡在函數(shù)返回值到另一個(gè)函數(shù)的傳遞,不知道如何來(lái)傳遞贷揽,不知道返回的值應(yīng)該如何用棠笑,而且本來(lái)是想用類(lèi)的,也是因?yàn)椴皇煜で菪鳎詿o(wú)奈選擇放棄蓖救,說(shuō)明基礎(chǔ)不扎實(shí),還得好好補(bǔ)一下函數(shù)和類(lèi)這一塊印屁,所以就選擇了scrapy
問(wèn)題二:
在爬取數(shù)據(jù)保存的過(guò)程中
第一次是保存成csv文件的循捺,但是很奇怪,會(huì)多次出現(xiàn)大量空行雄人,不知道是什么原因造成的巨柒,第二次是保存到mysql文件的,保存了幾百個(gè)數(shù)據(jù)后就停止了柠衍,而且在程序運(yùn)行中反復(fù)出現(xiàn)以下提示:

錯(cuò)誤提示

一開(kāi)始以為是positionName的原因,然后在positionName那里加了try語(yǔ)句還是出現(xiàn)這樣的提示晶乔,不知道如何解決珍坊。

感謝

在做作業(yè)的過(guò)程中,非常感覺(jué)@liang和@程老哥 幫助正罢,這么晚了還這么有耐心的幫忙解決問(wèn)題阵漏,真得是非常感謝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市履怯,隨后出現(xiàn)的幾起案子回还,更是在濱河造成了極大的恐慌,老刑警劉巖叹洲,帶你破解...
    沈念sama閱讀 221,406評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柠硕,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡运提,警方通過(guò)查閱死者的電腦和手機(jī)蝗柔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)民泵,“玉大人癣丧,你說(shuō)我怎么就攤上這事≌蛔保” “怎么了胁编?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,815評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鳞尔。 經(jīng)常有香客問(wèn)我嬉橙,道長(zhǎng),這世上最難降的妖魔是什么铅檩? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,537評(píng)論 1 296
  • 正文 為了忘掉前任憎夷,我火速辦了婚禮,結(jié)果婚禮上昧旨,老公的妹妹穿的比我還像新娘拾给。我一直安慰自己,他們只是感情好兔沃,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布蒋得。 她就那樣靜靜地躺著,像睡著了一般乒疏。 火紅的嫁衣襯著肌膚如雪额衙。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,184評(píng)論 1 308
  • 那天怕吴,我揣著相機(jī)與錄音窍侧,去河邊找鬼。 笑死转绷,一個(gè)胖子當(dāng)著我的面吹牛伟件,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播议经,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼斧账,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼谴返!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起咧织,我...
    開(kāi)封第一講書(shū)人閱讀 39,668評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤嗓袱,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后习绢,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體渠抹,經(jīng)...
    沈念sama閱讀 46,212評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評(píng)論 3 340
  • 正文 我和宋清朗相戀三年毯炮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逼肯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,438評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡桃煎,死狀恐怖篮幢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情为迈,我是刑警寧澤三椿,帶...
    沈念sama閱讀 36,128評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站葫辐,受9級(jí)特大地震影響搜锰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜耿战,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評(píng)論 3 333
  • 文/蒙蒙 一蛋叼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧剂陡,春花似錦狈涮、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,279評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至晕鹊,卻和暖如春松却,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背溅话。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,395評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工逾礁, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留熊户,地道東北人坞嘀。 一個(gè)月前我還...
    沈念sama閱讀 48,827評(píng)論 3 376
  • 正文 我出身青樓微渠,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親循狰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子窟社,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評(píng)論 2 359

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