Python 爬虫 PhantomJs 获取JS动态数据

上篇文章我非常high的爬取了一个正常网页的数据
对是正常

不正常的来了

这次研究的就是那些“不正常”的网页 当时是我太天真 后面发现水又深
介于现在JS H5的大趋势 大部分网站都是混入了JS数据加载 数据是延迟加载的

这样如果我们用原始的urllib.open(url) 加载出来的都是还没有加载js数据之前的 所以爆炸了

所以按照上篇文章那么正常的提取数据显然不可取了 那毕竟那是静态的 战场上 敌人也不会像抗日神剧剧情一样让你当靶子不是

我当时的想法就是要让让网页JS渲染数据加载完全了 我们才开始解析 这样才行 想想就行了 然而我并不会


并不会

后面查了一些资料

  • 无非两种实现
    1 分析JS源码 找出请求 自己模拟实现 难度比较高 麻烦
    2 模拟浏览器实现 三方库多 简单 但是效率会慢一点

然后搜到了很多相关的库 这里使用的是 Selenium + PhantomJs 网上推荐比较多

  • Selenium是一个用于Web应用程序测试的工具
  • Phantom JS是一个服务器端的 JavaScript API 的 WebKit

看了一下Selenium的Api 发现没有PhantomJS 他也可以使用FireFox来实现如同PhantomJs的功能
介于网上都是推荐PhantomJS 所以我也这样实现
Selenium就像一个大容器 里面放着PhantomJs来实现JS的渲染 我们直接操作Selenium的Api就行

这次选取的目标是 淘宝模特的网站 为什么是这个呢 除了美女多


美女多就够了

还有就是我学习的资料就是用的这个
Python学习的网站这个里面就是用这个作为实例
但是这个后续可能因为淘宝改版了网站结构 他的例子不能成功 所以我才研究JS的动态加载

开始套路 这里环境Windows
1 安装Selenium 用Pip 安装 如果Pip不能被找到 记得设置环境变量Python/Script
2 下载PhantomJs 然后将 解压后的执行文件放在被设置过环境变量的地方 不设置的话 后续代码就要设置 所以这里直接放进来方便


Paste_Image.png

这里检查一下

Paste_Image.png

能找到 说明Ok

下面是全部实现代码

官网的一些配置
#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:
        #头像,个人详情,名字,年龄,地区
            print u'发现一位MM 名字叫%s 年龄%s 坐标%s'%(item[2],item[3],item[4])
            print u'%s的个人主页是 %s'%(item[2],item[1])
            print u'继续获取详情页面数据...'
        #详情页面
            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'
            #保存个人信息
        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()
        #保存个人信息 以及耗时
        try:self.saveBrief(brief,dir,name,end_time-begin_time)
        except Exception,e:
            print u'保存个人信息失败 %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()

    #保存个人信息
    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'))

#创建目录
    def mkdir(self,path):
        path=path.strip()
        print u'创建目录%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

妹子不得来告我吧

闭着眼睛删除

声明一遍 如果有不能展示的 联系我 我会删掉的。。。


Paste_Image.png

现在来分析一下 实现过程

  • 第一页 任务列表 正常网页 看看结构 来用正则获取任务详情页面
Paste_Image.png
Paste_Image.png
  • 页面详情 使用PhantomJS 来加载 然后根据Xpath来获取 XPath是个宝贝啊 特别好用很粗暴一下子可以拿到想要的
粗暴提取

上篇文章有相关资料 不做详细分析 这个丑丑的正则

  1. 基本信息获取 观察结构



    对应的代码


    获取基本信息
  2. 然后头像也是一样


    Paste_Image.png

    获取头像
  3. 获取相册地址 进入相册页面



    获取相册链接


  4. 最后在相册里面获取第一页展示的

相册列表结构分析
拿到相册数据
下载相册内容

到此结束 保存相关信息的代码 上面也给出了 这里不做详细说明

基本分析 就是用google浏览器的F12 来分析结构 然后 抽取内容 感觉Python 相关资料很少啊 尤其是中文的
这个PhantomJs 之所以这里给出分享过程 因为我确实在Google 知乎(度娘更不用说了)上面搜索相关资料很少 别人也就说用这个 也没说咋用 对于新手来讲 还是希望能有一个完整的过程分析

嘿嘿嘿

写的时候听的歌
我等到花儿都谢了
我睡不着的时候会不会有人陪着我
我难过的时候会不会有人安慰我
我想说话的时候会不会有人了解我
我忘不了你的时候你会不会来疼我

不会
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容