欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PhantomJS+Selenium爬取淘宝

程序员文章站 2022-03-07 20:01:01
...

动态网页处理

很多网站都采用AJAX技术,SPA技术,部分内容都是异步动态加载的。可以提高用户体验。
但是,对于爬虫程序爬取到的HTML页面相当于页面模板,动态内容不再其中。
解决办法之一,如果能构造一个包含JS引擎的浏览器,让它加载网页并和网站交互,我们编程从这个浏览器获取内容包括动态内容。

PhantomJS

它是一个headless无头浏览器,支持JavaScript。可以运行在windows、linux、mac os等。所谓的无头浏览器就是包含JS引擎,浏览器排版引擎等核心组件,但是没有和用户交互的界面浏览器。
官网
http://phantomjs.org/
Casper下载地址:
http://casperjs.org/

PhantomJS是可以运行js脚本,下面有个例子

PhantomJS+Selenium爬取淘宝
PhantomJS+Selenium爬取淘宝
访问浏览器对象
PhantomJS+Selenium爬取淘宝
phantomjs的webpage模块

// 加载模块
var webPage = require('webpage');
// 创建对象
var page = webPage.create();
//打开页面
// page.open(
//     'https://www.baidu.com/',
//     function(status) {
//         console.log('请求响应状态码',status)
//         phantom.exit();
//     }
// );
//
 page.open(
     'https://fanyi.baidu.com/sug',
     'POST',
     'kw=test',
     function(status) {
         console.log('请求响应状态码',status)
         console.log(page.content)
         phantom.exit();
     }
 );

将example中的hello改成上面的代码,在cmd中 运行js脚本
PhantomJS+Selenium爬取淘宝

var webPage = require('webpage');
// 创建对象
var page = webPage.create();
page.open(
    'http://www.huanqiu.com/',
    function (status) {
        console.log('evaluate:', status)
        result = page.evaluate(function (p1) {
            // console.log('测试参数:',p1);   // 这个内部执行,不输出
            str_agent = window.navigator.userAgent;   // 得到浏览器的user-agent
            str_title = window.document.title;   // 文档标题 window可以省略
            // 下面访问DOM
            var node = document.querySelector('body > div.wrap > div.navTop > div > div > div.navTopOther > a.wxLogo');
            var dom_title = node.attributes['title'].value
            return [p1, str_agent, str_title, dom_title];

        }, '参数1');
        console.log('处理结果', result)
        phantom.exit();
    }

需要保存页面图片的话 在function内加render函数 具体代码如下
`
var webPage = require(‘webpage’);
// 创建对象
var page = webPage.create();
page.open(
http://www.huanqiu.com/’,
function(status) {
console.log(‘请求响应状态码’,status);
page.render(
‘huanqiu.png’,
{
format: ‘png’,
quality: 100
});
phantom.exit();
}
);

page.onLoadStarted = function () {
console.log(‘页面加载完毕’);
}`

Selenium

Selenium是一个自动化测试的工具。它可以直接运行在浏览器中,支持主流的浏览器,包括PhantomJS
在pycharm中 pip install 即可安装
下面我们来看看如何使用

from selenium.webdriver.chrome.options import Options
from selenium.webdriver import PhantomJS
from selenium.webdriver.phantomjs.webdriver import WebDriver
from selenium.webdriver.common.by import By
import time
options = Options()
options.headless = False

driver = PhantomJS('E:/phantomjs/bin/phantomjs.exe')
driver.set_window_size(1280,1080) #有的浏览器是你拉取多大 显示多少内容  所以尽量设置大一点
driver.get('https://login.taobao.com')
driver.save_screenshot('C:/Users/Administrator/PycharmProjects/test/test.png')

PhantomJS+Selenium爬取淘宝

处理异步请求

bing的查询结果是通过异步请求返回结果,多以,直接访问页面不能直接获取搜索结果

from selenium.webdriver import PhantomJS
from selenium.webdriver.phantomjs.webdriver import WebDriver

driver = PhantomJS('E:/phantomjs/bin/phantomjs.exe')
driver.set_window_size(1280,1080) 
driver.get('https://cn.bing.com/search?q=%E5%89%91%E6%9D%A5&qs=n&form=QBLH&sp=-1&pq=jianl&sc=8-5&sk=&cvid=8E8155699B16437BA16D9788700EABAC')
driver.save_screenshot('C:/Users/Administrator/PycharmProjects/test/test1.png')

PhantomJS+Selenium爬取淘宝
由于异步请求 加载需要时间 这里我们延迟三秒在保存图片
代码同上 在保存图片前加time.sleep(3)
PhantomJS+Selenium爬取淘宝

模拟键盘操作

这里我们模拟百度关键字搜索


from selenium.webdriver.chrome.options import Options
from selenium.webdriver import PhantomJS
import time
options = Options()
options.headless = False
driver = PhantomJS('E:/phantomjs/bin/phantomjs.exe')
driver.set_window_size(1280,1080) #有的浏览器是你拉取多大 显示多少内容  所以尽量设置大一点
driver.get('https://www.baidu.com')
try:
    input= driver.find_element_by_id('kw')
    input.send_keys('zzh')
    submit = driver.find_element_by_id('su')
    submit.click()
except:
    raise Exception

driver.save_screenshot('C:/Users/Administrator/PycharmProjects/test/test3.png')

PhantomJS+Selenium爬取淘宝

下拉框和上面操作差不多 f12找到下拉框的位置 然后用xpath定位 用Select保存元素操作
元素的值只有两种find方式 一个通过index 一个通过value

页面等待

越来越多的页面采用AJAX这样的异步技术,这导致页面代码中要访问的元素,没有被加载就被访问了,抛出异常
解决方法一:
上面使用的线程休眠,使用time.sleep来等待数据加载
方法二:Selenium等待
Selenium等待有两种:显示等待和隐式等待

显示等待

指定一个条件,一直等到这个条件成立后继续执行,也可以设置超时时间,超时抛异常
| expected_conditions | 说明 |
| presence_of_element_located | 判断某个元素是否被加载到DOM树里,但不一定是可见的
| visibility_of_element_located | 判断元素是否可见 |
| invisibility_of_element_located | 判断某个元素没被加载到DOM树里或不可见的 |
| element_to_be_clickable | 某个元素是否可见且可被点击 |

from selenium.webdriver import PhantomJS
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

driver = PhantomJS('E:/phantomjs/bin/phantomjs.exe')
driver.set_window_size(1280,1080) #有的浏览器是你拉取多大 显示多少内容  所以尽量设置大一点
driver.get('https://www.baidu.com')
try:
    ele= WebDriverWait(driver,10).until(
        EC.presence_of_element_located  #元素已加载到DOM,但不保证是可见的
        ((By.ID,'111')
                                       ))
except Exception as e:
    print(e)

finally:
    driver.quit()

PhantomJS+Selenium爬取淘宝
打印type(e)是超时异常 ,并不是找不到

隐式等待

隐式等待等于加载了配置,所以访问元素都等待特定的时间

from selenium.webdriver import PhantomJS
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

driver = PhantomJS('E:/phantomjs/bin/phantomjs.exe')
driver.set_window_size(1280,1080) #有的浏览器是你拉取多大 显示多少内容  所以尽量设置大一点
driver.implicitly_wait(10) #隐式等待
driver.get('https://www.baidu.com')
try:
    ele= driver.find_element_by_id('111')
except Exception as e:
    print(e,type(e))

finally:
    driver.quit()

PhantomJS+Selenium爬取淘宝
这里显示没找到异常

Phantomjs+Selenuim爬取淘宝

from selenium.webdriver import PhantomJS
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
import time

driver = PhantomJS('E:/phantomjs/bin/phantomjs.exe')
driver.set_window_size(1280,1080) #有的浏览器是你拉取多大 显示多少内容  所以尽量设置大一点
# driver.implicitly_wait(10) #隐式等待
driver.get('https://www.taobao.com')
try:
    ele= driver.find_element_by_xpath('//*[@id="J_SiteNavLogin"]/div[1]/div[1]/a[1]')
    print(type(ele))
    time.sleep(3)
    ele.click()
    time.sleep(3)
    username  =driver.find_element_by_xpath('//*[@id="TPL_username_1"]')
    time.sleep(3)
    username.send_keys('17356526030')
    time.sleep(3)
    password = driver.find_element_by_xpath('//*[@id="TPL_password_1"]')
    password.send_keys('zzh807651901.')
    driver.save_screenshot('C:/Users/Administrator/PycharmProjects/test/log.png')
    time.sleep(3)
    button = driver.find_element_by_xpath('//*[@id="J_SubmitStatic"]')
    time.sleep(3)
    button.click()
    time.sleep(3)
    driver.save_screenshot('C:/Users/Administrator/PycharmProjects/test/PlantomJS2.png')

except Exception as e:
    print(e,type(e))

finally:
    driver.save_screenshot('C:/Users/Administrator/PycharmProjects/test/PlantomJS3.png')
    driver.quit()

PhantomJS+Selenium爬取淘宝

相关标签: 爬虫