Python 爬蟲 PhantomJs 獲取JS動態(tài)數(shù)據(jù)

上篇文章我非常high的爬取了一個正常網(wǎng)頁的數(shù)據(jù)
對是正常

不正常的來了

這次研究的就是那些“不正辰淞迹”的網(wǎng)頁 當時是我太天真 后面發(fā)現(xiàn)水又深
介于現(xiàn)在JS H5的大趨勢 大部分網(wǎng)站都是混入了JS數(shù)據(jù)加載 數(shù)據(jù)是延遲加載的

這樣如果我們用原始的urllib.open(url) 加載出來的都是還沒有加載js數(shù)據(jù)之前的 所以爆炸了

所以按照上篇文章那么正常的提取數(shù)據(jù)顯然不可取了 那畢竟那是靜態(tài)的 戰(zhàn)場上 敵人也不會像抗日神劇劇情一樣讓你當靶子不是

我當時的想法就是要讓讓網(wǎng)頁JS渲染數(shù)據(jù)加載完全了 我們才開始解析 這樣才行 想想就行了 然而我并不會


并不會

后面查了一些資料

  • 無非兩種實現(xiàn)
    1 分析JS源碼 找出請求 自己模擬實現(xiàn) 難度比較高 麻煩
    2 模擬瀏覽器實現(xiàn) 三方庫多 簡單 但是效率會慢一點

然后搜到了很多相關的庫 這里使用的是 Selenium + PhantomJs 網(wǎng)上推薦比較多

  • Selenium是一個用于Web應用程序測試的工具
  • Phantom JS是一個服務器端的 JavaScript API 的 WebKit

看了一下Selenium的Api 發(fā)現(xiàn)沒有PhantomJS 他也可以使用FireFox來實現(xiàn)如同PhantomJs的功能
介于網(wǎng)上都是推薦PhantomJS 所以我也這樣實現(xiàn)
Selenium就像一個大容器 里面放著PhantomJs來實現(xiàn)JS的渲染 我們直接操作Selenium的Api就行

這次選取的目標是 淘寶模特的網(wǎng)站 為什么是這個呢 除了美女多


美女多就夠了

還有就是我學習的資料就是用的這個
Python學習的網(wǎng)站這個里面就是用這個作為實例
但是這個后續(xù)可能因為淘寶改版了網(wǎng)站結構 他的例子不能成功 所以我才研究JS的動態(tài)加載

開始套路 這里環(huán)境Windows
1 安裝Selenium 用Pip 安裝 如果Pip不能被找到 記得設置環(huán)境變量Python/Script
2 下載PhantomJs 然后將 解壓后的執(zhí)行文件放在被設置過環(huán)境變量的地方 不設置的話 后續(xù)代碼就要設置 所以這里直接放進來方便


Paste_Image.png

這里檢查一下

Paste_Image.png

能找到 說明Ok

下面是全部實現(xiàn)代碼

官網(wǎng)的一些配置
#coding=utf-8
__author__ = 'Daemon'

import urllib2,re,os,datetime
from selenium import webdriver

class Spider:
    def __init__(self):
        self.page=1
        self.dirName='MMSpider'
        #這是一些配置 關閉loadimages可以加快速度 但是第二頁的圖片就不能獲取了打開(默認)
        cap = webdriver.DesiredCapabilities.PHANTOMJS
        cap["phantomjs.page.settings.resourceTimeout"] = 1000
        #cap["phantomjs.page.settings.loadImages"] = False
        #cap["phantomjs.page.settings.localToRemoteUrlAccessEnabled"] = True
        self.driver = webdriver.PhantomJS(desired_capabilities=cap)

    def getContent(self,maxPage):
        for index in range(1,maxPage+1):
            self.LoadPageContent(index)

#獲取頁面內容提取
    def LoadPageContent(self,page):
        #記錄開始時間
        begin_time=datetime.datetime.now()
        url="https://mm.taobao.com/json/request_top_list.htm?page="+str(page)
        self.page+=1;

        USER_AGENT='Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36'
        headers = {'User-Agent':USER_AGENT }

        request=urllib2.Request(url,headers=headers)
        response=urllib2.urlopen(request)

        #正則獲取
        pattern_link=re.compile(r'<div.*?class="pic-word">.*?<img src="(.*?)".*?'
                            r'<a.*?class="lady-name".*?href="(.*?)".*?>(.*?)</a>.*?'
                            r'<em>.*?<strong>(.*?)</strong>.*?'
                            r'<span>(.*?)</span>'
                             ,re.S)
        items=re.findall(pattern_link,response.read().decode('gbk'))

        for item in items:
        #頭像噪猾,個人詳情凑耻,名字鹰祸,年齡鬼悠,地區(qū)
            print u'發(fā)現(xiàn)一位MM 名字叫%s 年齡%s 坐標%s'%(item[2],item[3],item[4])
            print u'%s的個人主頁是 %s'%(item[2],item[1])
            print u'繼續(xù)獲取詳情頁面數(shù)據(jù)...'
        #詳情頁面
            detailPage=item[1]
            name=item[2]
            self.getDetailPage(detailPage,name,begin_time)

    def getDetailPage(self,url,name,begin_time):
        url='http:'+url
        self.driver.get(url)
        base_msg=self.driver.find_elements_by_xpath('//div[@class="mm-p-info mm-p-base-info"]/ul/li')
        brief=''
        for item in base_msg:
            print item.text
            brief+=item.text+'\n'
            #保存?zhèn)€人信息
        icon_url=self.driver.find_element_by_xpath('//div[@class="mm-p-model-info-left-top"]//img')
        icon_url=icon_url.get_attribute('src')

        dir=self.dirName+'/'+name
        self.mkdir(dir)

    #保存頭像
        try:
            self.saveIcon(icon_url,dir,name)
        except Exception,e:
            print u'保存頭像失敗 %s'%e.message

    #開始跳轉相冊列表
        images_url=self.driver.find_element_by_xpath('//ul[@class="mm-p-menu"]//a')
        images_url=images_url.get_attribute('href')
        try:
            self.getAllImage(images_url,name)
        except Exception,e:
            print u'獲取所有相冊異常 %s'%e.message

        end_time=datetime.datetime.now()
        #保存?zhèn)€人信息 以及耗時
        try:self.saveBrief(brief,dir,name,end_time-begin_time)
        except Exception,e:
            print u'保存?zhèn)€人信息失敗 %s'%e.message


#獲取所有圖片
    def getAllImage(self,images_url,name):
        self.driver.get(images_url)
    #只獲取第一個相冊
        photos=self.driver.find_element_by_xpath('//div[@class="mm-photo-cell-middle"]//h4/a')
        photos_url=photos.get_attribute('href')

        #進入相冊頁面獲取相冊內容
        self.driver.get(photos_url)
        images_all=self.driver.find_elements_by_xpath('//div[@id="mm-photoimg-area"]/a/img')

        self.saveImgs(images_all,name)


    def saveImgs(self,images,name):
        index=1
        print u'%s 的相冊有%s張照片, 嘗試全部下載....'%(name,len(images))

        for imageUrl in images:
            splitPath = imageUrl.get_attribute('src').split('.')
            fTail = splitPath.pop()
            if len(fTail) > 3:
                fTail = "jpg"
            fileName = self.dirName+'/'+name +'/'+name+ str(index) + "." + fTail
            print u'下載照片地址%s '%fileName

            self.saveImg(imageUrl.get_attribute('src'),fileName)
            index+=1


    def saveIcon(self,url,dir,name):
        print u'頭像地址%s %s '%(url,name)

        splitPath=url.split('.')
        fTail=splitPath.pop()
        fileName=dir+'/'+name+'.'+fTail
        print fileName
        self.saveImg(url,fileName)

    #寫入圖片
    def saveImg(self,imageUrl,fileName):
        print imageUrl
        u=urllib2.urlopen(imageUrl)
        data=u.read()
        f=open(fileName,'wb')
        f.write(data)
        f.close()

    #保存?zhèn)€人信息
    def saveBrief(self,content,dir,name,speed_time):
        speed_time=u'當前MM耗時 '+str(speed_time)
        content=content+'\n'+speed_time

        fileName=dir+'/'+name+'.txt'
        f=open(fileName,'w+')
        print u'正在獲取%s的個人信息保存到%s'%(name,fileName)
        f.write(content.encode('utf-8'))

#創(chuàng)建目錄
    def mkdir(self,path):
        path=path.strip()
        print u'創(chuàng)建目錄%s'%path
        if os.path.exists(path):
            return False
        else:
            os.makedirs(path)
            return True

spider=Spider()
#獲取前5頁
spider.getContent(5)

效果如下 只獲取了第一個相冊的第一頁的 如果要全部的 還要涉及到模擬下滑加載更多這里先不作了解:

Paste_Image.png
Paste_Image.png

妹子不得來告我吧

閉著眼睛刪除

聲明一遍 如果有不能展示的 聯(lián)系我 我會刪掉的丹壕。箩兽。。


Paste_Image.png

現(xiàn)在來分析一下 實現(xiàn)過程

  • 第一頁 任務列表 正常網(wǎng)頁 看看結構 來用正則獲取任務詳情頁面
Paste_Image.png
Paste_Image.png
  • 頁面詳情 使用PhantomJS 來加載 然后根據(jù)Xpath來獲取 XPath是個寶貝啊 特別好用很粗暴一下子可以拿到想要的
粗暴提取

上篇文章有相關資料 不做詳細分析 這個丑丑的正則

  1. 基本信息獲取 觀察結構



    對應的代碼


    獲取基本信息
  2. 然后頭像也是一樣


    Paste_Image.png

    獲取頭像
  3. 獲取相冊地址 進入相冊頁面



    獲取相冊鏈接


  4. 最后在相冊里面獲取第一頁展示的

相冊列表結構分析
拿到相冊數(shù)據(jù)
下載相冊內容

到此結束 保存相關信息的代碼 上面也給出了 這里不做詳細說明

基本分析 就是用google瀏覽器的F12 來分析結構 然后 抽取內容 感覺Python 相關資料很少啊 尤其是中文的
這個PhantomJs 之所以這里給出分享過程 因為我確實在Google 知乎(度娘更不用說了)上面搜索相關資料很少 別人也就說用這個 也沒說咋用 對于新手來講 還是希望能有一個完整的過程分析

嘿嘿嘿

寫的時候聽的歌
我等到花兒都謝了
我睡不著的時候會不會有人陪著我
我難過的時候會不會有人安慰我
我想說話的時候會不會有人了解我
我忘不了你的時候你會不會來疼我

不會
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末葫辐,一起剝皮案震驚了整個濱河市搜锰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌耿战,老刑警劉巖蛋叼,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異剂陡,居然都是意外死亡狈涮,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門鸭栖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歌馍,“玉大人,你說我怎么就攤上這事晕鹊∷扇矗” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵溅话,是天一觀的道長晓锻。 經(jīng)常有香客問我,道長公荧,這世上最難降的妖魔是什么带射? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮循狰,結果婚禮上窟社,老公的妹妹穿的比我還像新娘。我一直安慰自己绪钥,他們只是感情好灿里,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著程腹,像睡著了一般匣吊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寸潦,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天色鸳,我揣著相機與錄音,去河邊找鬼见转。 笑死命雀,一個胖子當著我的面吹牛,可吹牛的內容都是我干的斩箫。 我是一名探鬼主播吏砂,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼撵儿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了狐血?” 一聲冷哼從身側響起淀歇,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎匈织,沒想到半個月后浪默,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡报亩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年浴鸿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弦追。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡岳链,死狀恐怖,靈堂內的尸體忽然破棺而出劲件,到底是詐尸還是另有隱情掸哑,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布零远,位于F島的核電站苗分,受9級特大地震影響,放射性物質發(fā)生泄漏牵辣。R本人自食惡果不足惜摔癣,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望纬向。 院中可真熱鬧择浊,春花似錦、人聲如沸逾条。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽师脂。三九已至担孔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吃警,已是汗流浹背糕篇。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留酌心,地道東北人娩缰。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像谒府,于是被迫代替她去往敵國和親拼坎。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內容