• Python3.x:Selenium+PhantomJS爬取带Ajax、Js的网页


    Python3.x:Selenium+PhantomJS爬取带Ajax、Js的网页

    前言 

      现在很多网站的都大量使用JavaScript,或者使用了Ajax技术。这样在网页加载完成后,url虽然不改变但是网页的DOM元素内容却可以动态的变化。如果处理这种网页是还用requests库或者python自带的urllib库那么得到的网页内容和网页在浏览器中显示的内容是不一致的。

    解决方案

      使用Selenium+PhantomJS。这两个组合在一起,可以运行非常强大的爬虫,可以处理cookie,JavaScript,header以及其他你想做的任何事情。 

    安装第三方库

      Selenium是一个强大的网络数据采集工具,最初是为网站自动化测试开发的,其有对应的Python库;

      Selenium安装命令:

    pip install selenium

    安装PhantomJS

      PhantomJS是一个基于webkit内核的无头浏览器,即没有UI界面,即它就是一个浏览器,只是其内的点击、翻页等人为相关操作需要程序设计实现。通过编写js程序可以直接与webkit内核交互,在此之上可以结合java语言等,通过java调用js等相关操作。需要去官网下载对应平台的压缩文件;

    PhantomJS(phantomjs-2.1.1-windows)下载地址:http://phantomjs.org/download.html

    下载PhantomJs 然后将 解压后的执行文件放在被设置过环境变量的地方,不设置的话,后续代码就要设, 所以这里直接放进来方便;

    然后检测下,在cmd窗口输入phantomjs:

    出现这样的画面,即表示成功;

    示例一:

      Selenium+PhantomJS示例代码:

    from selenium import webdriver
    
    driver = webdriver.PhantomJS()
    driver.get('http://www.cnblogs.com/lizm166/p/8360388.html')
    #获取网页源码
    data = driver.page_source
    print(data)
    #获取元素的html源码
    tableData = driver.find_element_by_tag_name('tableData').get_attribute('innerHTML')
    #获取元素的id值
    tableI = driver.find_element_by_tag_name('tableData').get_attribute('id')
    #获取元素的文本内容
    tableI = driver.find_element_by_tag_name('tableData').text
    #循环测试
    list_container = driver.find_elements_by_xpath("//div[@class='list-container mb-bg']/dl/dt/h3/a") 
    for title in list_container:  
        print 'Num' + str(SUMRESOURCES +1)  
        print u'标题: ' + title.text  
        print u'链接: ' + title.get_attribute('href')
    
    driver.quit()    

      能输出网页源码,说明安装成功

    示例二:

      通过这两者来解决客户端重定向问题的例子:

      程序首先加载了driver对象,然后请求网站,之后没0.5秒检测网站的html元素,如果html元素发生改变则认为页面发生了重定向,然后打印重定向后的页面内容。

      代码:

    from selenium import webdriver
    import time
    from selenium.webdriver.remote.webelement import WebElement
    from selenium.common.exceptions import StaleElementReferenceException
    
    
    # 处理重定向,可以定时检查页面的某元素
    # 如果和先前的不一致则可认为客户端重定向
    def wait_for_load(driver):
        #elem = driver.find_element_by_tag_name("html")
        title = driver.find_element_by_tag_name("title")
        #print(title)
        count = 0
        while True:
            count += 1
            if count > 20:
                print("Timing out after 10 seconds and returning")
                return
            time.sleep(.5)
    
            newtitle = driver.find_element_by_tag_name("title")
            if newtitle != title:
                return
            #try:
            #    elem = driver.find_element_by_tag_name("html")
            #except StaleElementReferenceException:
            #    return
    
    driver = webdriver.PhantomJS(executable_path='./phantomjs')
    driver.get("http://pythonscraping.com/pages/javascript/redirectDemo1.html")
    wait_for_load(driver)
    print(driver.page_source)

     示例三:

    import requests
    from bs4 import BeautifulSoup
    from selenium import webdriver
    
    def getData(dataUrl):
        #获取ajax返回的页面(用bs4获取不到ajax返回的数据)
        driver = webdriver.PhantomJS()
        driver.get(dataUrl)
        #获取table元素
        tables = driver.find_elements_by_tag_name('table')
        if tables is None:
            print('网页加载获取数据失败')
            logger.info('网页加载获取数据失败')
        #获取table元素中的tr元素
        trList = tables[0].find_elements_by_tag_name('tr')
        if trList is None:
            print('网页加载获取数据失败')
            logger.info('网页加载获取数据失败')
        for i in range(0,len(trList)):
            if i > 0:
                #获取table元素中的tr元素中的td元素
                tdList = trList[i].find_elements_by_tag_name('td')
                if tdList is not None:
                    for n in range(0,len(tdList)):
                        #获取td元素文本内容
                        print(">>>>%s:%s"%(n,tdList[n].text))
        driver.quit()
    
    def getDataUrl(issueid):
        dataUrl = ''
        url = "http://******/Scsj_tjyb_issue.jsp"
        headerDict = {'Host': '******',
                      'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.31 Safari/537.36',
                      'Accept': '*/*',
                      'Accept-Language': 'zh-CN,zh;q=0.8',
                      'Accept-Encoding': 'gzip, deflate',
                      'Origin':'http://******,
                      'Referer': 'http://******/tjyb_front/',
                      'Connection': 'keep-alive'}
        data = {'AJAX': '1', 'TEMPLATE_ID': '1114',
                'ISSUEID': issueid, 'CATALOGTYPE': 'main',
                'LANGUAGE': 'zh', 'HEAD': ''}
        res = requests.post(url, data=data, headers=headerDict)
        # 获取跳转后的页面源码,返回json串
        soup = BeautifulSoup(res.content, "html.parser")
        if soup.find_all('a',target='_blank') is not None:
            for a_url in soup.find_all('a',target='_blank'):
                if a_url.string == '******统计表':
                    dataUrl=a_url['href']
                    break
        else:
            print("未获取到a标签")
            logger.info("未获取到a标签")
        print('http://******'+dataUrl)
        return 'http://******'+dataUrl
    
    if __name__ == '__main__':
        url = getDataUrl('897')
        getData(url)

     示例四:

    #自定义请求头head
    from selenium import webdriver
    from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
    
    #设置自定义请求头参数
    def get_headers_driver():
        desire = DesiredCapabilities.PHANTOMJS.copy()
        headers = {'Accept': '*/*',
                   'Accept-Language': 'en-US,en;q=0.8',
                   'Cache-Control': 'max-age=0',
                   'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36',
                   'Connection': 'keep-alive',
                   'Referer': 'http://www.baidu.com/'
                   }
        for key, value in headers.items():
            desire['phantomjs.page.customHeaders.{}'.format(key)] = value
        driver = webdriver.PhantomJS(desired_capabilities=desire, service_args=['--load-images=yes'])#将yes改成no可以让浏览器不加载图片
        return driver
    
    # 登录
    def login():
        driver = get_headers_driver(cookie)
        url = "http://******/login/main.do"
        driver.get(url)
        #获取网页源码
        print(driver.page_source)

     注:模拟回车键代码

    # 模拟回车
    from selenium.webdriver.common.keys import Keys
    driver.find_element_by_xpath("**").send_keys(Keys.ENTER)
  • 相关阅读:
    Beta冲刺(5/7)——2019.5.26
    Beta冲刺(4/7)——2019.5.25
    Beta冲刺(3/7)——2019.5.24
    Echo团队Beta冲刺随笔集合
    Echo团队Alpha冲刺随笔集合
    用户体验报告(Echo)
    Echo团队 对 待就业六人组 和 SkyReach 的Beta产品测试报告
    Beta冲刺第七天
    Beta冲刺第六天
    Beta冲刺第五天
  • 原文地址:https://www.cnblogs.com/lizm166/p/8360388.html
Copyright © 2020-2023  润新知