PhantomJS+Selenium爬取淘宝
动态网页处理
很多网站都采用AJAX技术,SPA技术,部分内容都是异步动态加载的。可以提高用户体验。
但是,对于爬虫程序爬取到的HTML页面相当于页面模板,动态内容不再其中。
解决办法之一,如果能构造一个包含JS引擎的浏览器,让它加载网页并和网站交互,我们编程从这个浏览器获取内容包括动态内容。
PhantomJS
它是一个headless无头浏览器,支持JavaScript。可以运行在windows、linux、mac os等。所谓的无头浏览器就是包含JS引擎,浏览器排版引擎等核心组件,但是没有和用户交互的界面浏览器。
官网
http://phantomjs.org/
Casper下载地址:
http://casperjs.org/
PhantomJS是可以运行js脚本,下面有个例子
访问浏览器对象
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脚本
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')
处理异步请求
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')
由于异步请求 加载需要时间 这里我们延迟三秒在保存图片
代码同上 在保存图片前加time.sleep(3)
模拟键盘操作
这里我们模拟百度关键字搜索
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')
下拉框和上面操作差不多 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()
打印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+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()
上一篇: selinux的初级管理
下一篇: 图片下载器爬虫 ItemLoader