pyspider爬蟲爬攜程全國酒店遇到的坑慌盯,時(shí)間戳不能作為唯一標(biāo)識(shí)

時(shí)間戳格式化成字符串之后的結(jié)果:
自己看結(jié)果

>>> time.time()
1530150193.873144
>>> '{}'.format(time.time())
'1530150224.11'
>>> '{}'.format(str(time.time()))
'1530150237.7'
>>> a = 1.33333
>>> str(a)
'1.33333'
>>> str(time.time())
'1530151047.78'
>>> 

pyspider內(nèi)置url去重機(jī)制周霉,本想著,根據(jù)時(shí)間戳的唯一性來拼接url參數(shù)亚皂,達(dá)到url唯一性的目的俱箱,以至于不被自動(dòng)去重而丟失請求,但是事實(shí)上灭必,丟失了大量的請求;
問題代碼段:

        for i in range(1,pages+1):
            url = 'http://hotels.ctrip.com/Domestic/Tool/AjaxHotelList.aspx?time={}'.format(time.time())

由于cpu的運(yùn)算速度特別快狞谱,別說第二小數(shù)了,可能第6位小數(shù)都是重復(fù)的禁漓,那么這樣的url肯定被去重跟衅,
導(dǎo)致的結(jié)果,我在調(diào)試的時(shí)候529個(gè)請求播歼,有的時(shí)候是40多個(gè)伶跷,有的時(shí)候是50多個(gè),我就納悶了秘狞,到底是怎么回事叭莫,為什么會(huì)丟請求,后來想到烁试,前段時(shí)間的另一個(gè)問題:

self.send_message(self.project_name,data,url=time.time())

由于pyspider自帶數(shù)據(jù)去重雇初,相同的數(shù)據(jù)特征是不會(huì)被保存的,這里是根據(jù)url來識(shí)別特征的减响!
在調(diào)試中我發(fā)現(xiàn)所有的數(shù)據(jù)都拿到了靖诗,但是保存的時(shí)候,總是會(huì)丟失大量的數(shù)據(jù)支示;基本上會(huì)丟失9/10,也就是10條數(shù)據(jù)才能被保存一條刊橘;

突然恍然大悟:

萬惡的time.time()根本不能唯一標(biāo)識(shí);
于是修改代碼颂鸿,只需要修改一個(gè)地方伤为,就是將time.time()換成其他的唯一標(biāo)識(shí)符;
修改后的代碼如下:

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2018-06-21 10:35:32
# Project: ctrip_hotel
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
from pyspider.libs.base_handler import *
from lxml import etree
import random
import json
import time
from pyspider_util import proxy_util
from fake_useragent import UserAgent
import re
from pyspider.libs.base_handler import *
from lxml import etree
import random
import json
import time
from pyspider_util import proxy_util
from fake_useragent import UserAgent
import re
import hashlib

city_names = [u'上海', '北京', '廣州', '深圳', '南京', '廈門', '大連', '天津', '寧波', '成都', '無錫', '杭州', '武漢', '沈陽', '蘇州', '西安', '重慶', '長沙', '青島', '東莞', '烏魯木齊', '佛山', '南寧', '南昌', '南通', '合肥', '太原', '常州', '徐州', '惠州', '揚(yáng)州', '昆明', '汕頭', '泉州', '洛陽', '濟(jì)南', '海口', '溫州', '濰坊', '煙臺(tái)', '珠海', '石家莊', '福州', '貴陽', '鄭州', '金華', '長春', '哈爾濱', '三亞', '上饒', '中山', '臨沂', '麗江', '保定', '蘭州', '包頭', '南充', '南平', '臺(tái)州', '吉林', '呼倫貝爾', '呼和浩特', '咸陽', '唐山', '嘉興', '大慶', '威海', '安陽', '宜賓', '宜昌', '宜春', '寶雞', '岳陽', '常德', '廊坊', '張家口', '德陽', '懷化', '撫順', '揭陽', '柳州', '株洲', '桂林', '梅州', '榆林', '泰州', '瀘州', '濟(jì)寧', '淄博', '淮安', '湖州', '湛江', '漳州', '鹽城', '秦皇島', '紹興', '綿陽', '舟山', '蕪湖', '荊州', '莆田', '蚌埠', '衡陽', '衢州', '西寧', '贛州', '赤峰', '運(yùn)城', '連云港', '遵義', '邢臺(tái)', '邯鄲', '郴州', '鄂爾多斯', '銀川', '鎮(zhèn)江', '鞍山', '齊齊哈爾', '龍巖']
# type_code = ['100000', '100100', '100101', '100102', '100103', '100104', '100105', '100200', '100201']
class Handler(BaseHandler):
    crawl_config = {
        'proxy': 'forward.xdaili.cn:80'
    }
    ua = UserAgent()
    # 請求城市列表頁
    @every(minutes=365 * 24 * 60)
    def on_start(self):
        headers = {}
        headers = self.url_start(headers)
        url = 'http://hotels.ctrip.com/domestic-city-hotel.html?time={}'.format(time.time())
        self.crawl(url,headers=headers,callback=self.get_allcity_urls,retries=10)
    # 請求所有城市的url
    @config(age=364 * 24 * 60)
    def get_allcity_urls(self,response):
        tree = etree.HTML(response.text)
        all_list = tree.xpath('//dl[@class="pinyin_filter_detail layoutfix"]/dd/a')
        city_urls = []
        url_name = {}
        for i in all_list:
            name = i.xpath('./text()')[0]
            if name in city_names:
                city_urls.append(i.xpath('./@href')[0])
                url_name[i.xpath('./@href')[0]] = name
        print(city_urls)
        for city_url in city_urls:
            headers = {}
            headers = self.url_start(headers)
            city_url = 'http://hotels.ctrip.com' + city_url + '?time={}'.format(time.time())
            self.crawl(city_url,headers = headers,retries=10,callback=self.get_allpages,save=url_name)

    #拿到總頁數(shù)绞愚,發(fā)起所有列表頁的請求
    @config(age=364 * 24 * 60)
    def get_allpages(self,response):
        tree = etree.HTML(response.text)
        url_name = response.save
        url_e = re.findall(r'(/hotel/[a-z]+\d+)\?time=', response.url)[0]

        name = url_name[url_e]
        try:
            pages = tree.xpath('//div[@class="c_page_list layoutfix"]/a[@rel="nofollow"]/text()')[0]
            pages = int(pages)
        except:
            pages = 1
        print(pages)
        # python2
        import urllib
        print(name)
        name_code = urllib.quote(name.decode('utf-8').encode('utf-8'))
        city_id = re.findall(r'/hotel/[a-z]+(\d+)\?time=', response.url)[0]
        city_py = re.findall(r'/hotel/([a-z]+)\d+\?time=',response.url)[0]
        for i in range(1,pages+1):
            url = 'http://hotels.ctrip.com/Domestic/Tool/AjaxHotelList.aspx?time={}'.format(i)
            formdata = {
                           "__VIEWSTATEGENERATOR": "DB1FBB6D",
                           "cityName": name_code,
                           "RoomGuestCount": "1,1,0",
                           "operationtype": "NEWHOTELORDER",
                           "cityId": city_id,
                           "cityPY": city_py,
                           "page": i,
            }
            headers = {}
            headers = self.url_start(headers)
            self.crawl(url,method='POST', data=formdata,headers=headers,retries=10,callback=self.response_parse,save={'name':name})

    # 保存單頁的數(shù)據(jù)部分?jǐn)?shù)據(jù),發(fā)起詳情頁請求颖医,拿到更多數(shù)據(jù)位衩;
    @config(age=364 * 24 * 60)
    def response_parse(self, response):
        city_name = response.save['name']
        response_json = response.json
        info_list = response_json["hotelPositionJSON"]
        htllist = response_json['HotelMaiDianData']['value']['htllist']
        htllist = eval(htllist)
        num = 0
        for info in info_list:
            # 拿到列表頁酒店的部分?jǐn)?shù)據(jù),傳遞給詳情頁的請求
            info_json = {}
            info_json['id'] = info['id']
            info_json['名稱'] = info['name']
            info_json['地址'] = info['address']
            info_json['評分'] = info['score']
            star = info['star']
            if 'diamond' in star:
                info_json['攜程評級(jí)'] = star
                info['星級(jí)'] = ''
            else:
                info_json['攜程評級(jí)'] = ''
                info['星級(jí)'] = star
            info_json['類型'] = info['stardesc']
            info_json['省'] = ''
            info_json['市'] = city_name
            lon = info['lon']
            lat = info['lat']
            info_json['中心點(diǎn)'] = lon + lat
            info_json['最低價(jià)'] = htllist[num]['amount']
            # for ht in htllist:
            #     if ht['hotelid'] == info['id']:
            #         info_json['最低價(jià)'] = ht['amount']
            url = 'http://hotels.ctrip.com'+info['url']
            headers = {}
            headers = self.url_start(headers)
            num += 1
            self.crawl(url,headers=headers,retries=10, callback=self.detail_parse, save=info_json)

    # 解析詳情頁熔萧,拿到剩余字段糖驴,保存數(shù)據(jù)庫
    def detail_parse(self,response):
        tree = etree.HTML(response.text)
        #price = tree.xpath('//p[@class="staring_price"]/span[@class="price"]/text()')[0]
        special = tree.xpath('//div[@class="grade"]/div[@class="special_label"]/i[@class="i_label"]/text()')
        bar = tree.xpath('//div[@class="path_bar2"]/a/text()')
        if len(bar) == 3:
            district = bar[2]
            brand = ''
        elif len(bar) == 4:
            district = bar[3]
            brand = [2]
        else:
            district = ''
            brand = ''
        info_json = response.save
        #info_json['最低價(jià)'] = price
        info_json['品牌'] = brand
        info_json['所在區(qū)縣'] = district
        info_json['特色'] = special
        self.send_message(self.project_name, info_json, url=info_json['id'])

    def on_message(self, project_name, msg):
        return msg
    #
    def url_start(self, headers):
        times = int(time.time())
        planText = "orderno=ZF20186158891UccNQO,secret=fbba4b982cc64755b23404f99297ecbd,timestamp={}".format(times)
        md = hashlib.md5()
        md.update(planText.encode('utf-8'))
        content = md.hexdigest()
        ua = UserAgent()
        headers['User-Agent'] = ua.random
        headers['Proxy-Authorization'] = 'sign={}&orderno=ZF20186158891UccNQO&timestamp={}'.format(content.upper(),
                                                                                                   times)
        return headers



?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市佛致,隨后出現(xiàn)的幾起案子贮缕,更是在濱河造成了極大的恐慌,老刑警劉巖俺榆,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件感昼,死亡現(xiàn)場離奇詭異,居然都是意外死亡罐脊,警方通過查閱死者的電腦和手機(jī)定嗓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萍桌,“玉大人宵溅,你說我怎么就攤上這事∩涎祝” “怎么了恃逻?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長藕施。 經(jīng)常有香客問我寇损,道長,這世上最難降的妖魔是什么铅碍? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任润绵,我火速辦了婚禮,結(jié)果婚禮上胞谈,老公的妹妹穿的比我還像新娘尘盼。我一直安慰自己,他們只是感情好烦绳,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布卿捎。 她就那樣靜靜地躺著,像睡著了一般径密。 火紅的嫁衣襯著肌膚如雪午阵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機(jī)與錄音底桂,去河邊找鬼植袍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛籽懦,可吹牛的內(nèi)容都是我干的于个。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼暮顺,長吁一口氣:“原來是場噩夢啊……” “哼厅篓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起捶码,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤羽氮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后惫恼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體档押,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年尤筐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汇荐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡盆繁,死狀恐怖掀淘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情油昂,我是刑警寧澤革娄,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站冕碟,受9級(jí)特大地震影響拦惋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜安寺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一厕妖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧挑庶,春花似錦言秸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凳枝,卻和暖如春抄沮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工叛买, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砂代,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓率挣,卻偏偏與公主長得像泊藕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子难礼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

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