采集淘宝商品数据的时候,主要用到了Selenium+PhantomJS。在这个过程中对淘宝的严厉反爬措施佩服至极,个人也得到了很多成长。虽然历经曲折,最终还是能正常运行自己的脚本采集数据。
这里总结一下Selenium+PhantomJS使用中常用的操作。
设置等待时间隐式等待,等同于time.sleep()
driver.implicitly_wait(40)
设置PhantomJS发送和接收请求的相关参数
# 构造一个PHANTOMJS对象
phan = dict(DesiredCapabilities.PHANTOMJS)
# 在运行前修改对象参数
#设置user-agent请求头
UserAgent = "..."
phan["phantomjs.page.settings.userAgent"] = (UserAgent)
# 禁止加载图片
phan["phantomjs.page.settings.loadImages"] = False
# 设置请求cookie
phan["phantomjs.page.customHeaders.Cookie"] = 'SINAGLOBAL=3955422793326.2764.1451802953297;
'
# 禁用缓存
phan["phantomjs.page.settings.disk-cache"] = True
# 设置代理
service_args = ['--proxy=127.0.0.1:9999','--proxy-type=socks5']
# 加载自定义配置
driver = webdriver.PhantomJS(r"D:\phantomjs-2.1.1-windows\bin\phantomjs.exe",desired_capabilities=phan,service_args=service_args)
# 设定get url最大等待时间,规定时间内没有响应就会报错
# 类似于requests.get()的timeout选项,但driver.get()没有timeout选项
driver.set_page_load_timeout(40)
# 设置脚本超时时间
driver.set_script_timeout(10)
关于PhantomJS对象的settings 参数
phan["phantomjs.page.settings.xxxx"] = xxxx
该属性存储请求/接收的各种设置:
javascriptEnabled定义是否在页面中执行脚本(默认为true)。
loadImages定义是否加载内联图像(默认为true)。
localToRemoteUrlAccessEnabled定义本地资源(例如从文件)是否可以访问远程URL(默认为false)。
userAgent 定义当网页请求资源时发送到服务器的用户代理。
userName 设置用于HTTP身份验证的用户名。
password 设置用于HTTP身份验证的密码。
XSSAuditingEnabled定义是否应监视加载请求以进行跨站点脚本尝试(默认为false)。
webSecurityEnabled定义是否启用Web安全性(默认为true)。
resourceTimeout(以毫秒为单位)定义超时时间,所请求的资源将停止尝试并继续执行页面的其他部分。onResourceTimeout回调将在超时时调用。
切换到操作iframe
flag = driver.find_element_by_tag_name('iframe')
driver.switch_to.frame(flag)
切换回操作主窗口
driver.switch_to.default_content()
获得session_id page_source get_cookies()
browser.session_id
browser.page_source
browser.get_cookies()
另外使用phantomjs多线程会有异常卡死的情况,尽量使用多进程。
from multiprocessing import Pool
pool = Pool(8)
data_list = pool.map(func, url_list)
pool.close()
pool.join()
对于有可能异常退出情况,最好加一句driver.quit(),否则程序退出了但是phantomjs没有退出,一直占用资源。
driver.quit()
使用chrome时,可以隐藏chrome的界面运行
from pyvirtualdisplay import Display
display = Display(visible=0, size=(800,800))
display.start()
设置代理,清空缓存重新打开
利用DesiredCapabilities(代理设置)参数值,重新打开一个sessionId,我看意思就相当于浏览器清空缓存后,加上代理重新访问一次url
proxy=webdriver.Proxy()
proxy.proxy_type=ProxyType.MANUAL
proxy.http_proxy='1.9.171.51:800'
# 将代理设置添加到webdriver.DesiredCapabilities.PHANTOMJS中
proxy.add_to_capabilities(webdriver.DesiredCapabilities.PHANTOMJS)
browser.start_session(webdriver.DesiredCapabilities.PHANTOMJS)
browser.get('http://1212.ip138.com/ic.asp')
还原到系统(自己的ip)代理
proxy=webdriver.Proxy()
proxy.proxy_type=ProxyType.DIRECT
proxy.add_to_capabilities(webdriver.DesiredCapabilities.PHANTOMJS)
browser.start_session(webdriver.DesiredCapabilities.PHANTOMJS)
browser.get('http://1212.ip138.com/ic.asp')