爬虫动态渲染页面爬取之selenium驱动chrome浏览器的使用

Posted caiyundo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了爬虫动态渲染页面爬取之selenium驱动chrome浏览器的使用相关的知识,希望对你有一定的参考价值。

 

Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样,可以用其进行网页动态渲染页面的爬取

支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。

 

 

1. 示例

### selenium的使用
‘‘‘
Selenium是一个用于Web应用程序测试的工具。
Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。
‘‘‘

## 示例
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.wait import WebDriverWait

browser = webdriver.Chrome()
try:
    browser.get(https://www.baidu.com)
    input = browser.find_element_by_id(kw)
    input.send_keys(Python)
    input.send_keys(Keys.ENTER)
    wait = WebDriverWait(browser, 10)
    wait.until(ec.presence_of_element_located((By.ID, content_left)))
    print(browser.page_source)
    print(browser.current_url)
    print(browser.get_cookies())
finally:
    browser.close()

 

2. 声明浏览器对象

## 声明浏览器对象
from selenium import webdriver

# 声明1个chrome浏览器对象
browser1 = webdriver.Chrome()
# 声明1个firefox浏览器对象
browser2 = webdriver.Firefox()
# 声明1个edge浏览器对象
browser3 = webdriver.Edge()
# 声明1个safari浏览器对象
browser4 = webdriver.Safari()
# 声明1个phantonjs无界面浏览器对象
browser5 = webdriver.PhantomJS()

  

3. get方法访问页面

## 访问页面,get方法
from selenium import webdriver

# 声明浏览器对象
browser = webdriver.Chrome()
# 访问淘宝主页
browser.get(https://www.taobao.com)
# 打印访问到的页面源码
print(browser.page_source)
# 关闭浏览器
browser.close()

 

4. 查找节点 

## 查找节点
## element返回单个节点对象,
## elements返回多个节点对象的列表
# 1.根据id、class、name、text、tag等的值获取:find_element_by_id,
# 2.通过css选择器获取:find_element_by_css_selector
# 3.通过xpath方法获取:find_element_by_xpath
from selenium import webdriver
from selenium.webdriver.common.by import By

browser = webdriver.Chrome()
browser.get(https://www.taobao.com)
input_1 = browser.find_element_by_id(q)
input_2 = browser.find_element_by_css_selector(#q)
input_3 = browser.find_element_by_xpath(//input[@id="q"])
# 查找节点的其他写法
input_other = browser.find_element(By.CSS_SELECTOR, #q)
# 查找多个节点,返回匹配到的对象的列表
elements = browser.find_elements(By.XPATH, //*[contains(@class, "service-bd")]//li)

print(type(elements), elements)
print(input_1, input_2, input_3, input_other)
print(type(input_1), type(input_2), type(input_3), type(input_other))
browser.close()

 

5. 节点间进行交互

## 节点交互
## 输入内容send_keys
## 清空内容clear
## 触发点击click
import time
from selenium import webdriver

browser = webdriver.Chrome()
browser.get(https://www.taobao.com)
input = browser.find_element_by_id(q)
input.send_keys(电脑)
time.sleep(2)
input.clear()
input.send_keys(手机)
button = browser.find_element_by_xpath(//button[contains(@class, "btn-search")])
button.click()
time.sleep(2)

browser.close()

 

6. 动作链,鼠标拖拽,键盘按键等

## 动作链,鼠标拖拽,键盘按键等
from selenium import webdriver
from selenium.webdriver import ActionChains

browser = webdriver.Chrome()
url = http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable
browser.get(url)
# webDriver只能在一个页面上对元素识别和定位,对于frame/iframe表单内嵌页面上的元素无法直接定位,
# 此时就需要通过switch_to.frame()方法将当前定位的主题切换为iframe表单的内嵌页面中。
browser.switch_to.frame(iframeResult) drag = browser.find_element_by_id(draggable) drop = browser.find_element_by_id(droppable) # 声明对象 action = ActionChains(browser) # 调用drag_and_drop方法 action.drag_and_drop(drag, drop) # 执行刚刚调用的方法 action.perform() browser.close()

 

7. 执行javascript 

## 执行JavaScript
from selenium import webdriver

browser = webdriver.Chrome()
browser.get(https://www.mi.com/)
browser.execute_script(window.scrollTo(0, document.body.scrollHeight))
browser.execute_script(alert("已到底部"))

 

8. 获取节点信息,如text,attribute等 

## 获取节点信息
from selenium import webdriver

browser = webdriver.Chrome()
browser.get(https://www.taobao.com)
s = browser.find_element_by_id(tb-beacon-aplus)
print(type(s), s)
# 获取s节点的src属性信息
print(s.get_attribute(src))

s2 = browser.find_element_by_class_name(site-nav-menu-hd)
# 获取节点的文本信息
print(s2.text)
# 获取节点的id
print(s2.id)
# 获取节点的标签名
print(s2.tag_name)
# 获取节点基于页面的相对位置
print(s2.location)
# 获取节点内容的大小,即占据页面的长度以及宽度
print(s2.size)

browser.close()

 

9. 切换Frame

## 切换Frame
# 网页中有一种iframe节点,iframe节点里的内容相当于页面的子页面,子页面内容结构和正常网页结构完全一致
# selenium打开页面时只能获取到父级Frame页面的内容,要想获取子页面内容,需要switch_to.frame()方法来切换页面
from selenium import webdriver
from selenium.common import exceptions

browser = webdriver.Chrome()
url = http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable
browser.get(url)
try:
    browser.find_element_by_id(droppable)
except exceptions.NoSuchElementException:
    print(NO element...)
# 切换frame
browser.switch_to.frame(iframeResult)
s = browser.find_element_by_id(droppable)
print(s)

 

10. 延时等待

## 延时等待
## 隐式等待,类似于time.sleep
## 显式等待,当检测到某个节点内容后即返回,推荐使用
# 隐式等待
from selenium import webdriver

browser = webdriver.Chrome()
browser.implicitly_wait(10)
browser.get(https://www.taobao.com)
input = browser.find_element_by_id(q)
print(input.tag_name)

browser.close()

# 显式等待
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

browser = webdriver.Chrome()
browser.get(https://www.taobao.com)
# 基于browser构建一个等待对象,等待最大时间为10s
wait = WebDriverWait(browser, 10)
# 等待10s时间内,如果页面出现id="q"节点时,则返回节点并且程序继续执行,否则抛出异常,程序结束
# presence_of_element_located中进行判断节点是否出现,传入一个元组
w = wait.until(EC.presence_of_element_located((By.ID, q)))
input = browser.find_element_by_id(q)
print(w.id, input.tag_name)

browser.close()

‘‘‘
其他等待条件说明:
title_is                                    标题是某内容
title_contains                              标题包含某内容
presence_of_element_located                 节点加载出来(传入元组(By.ID, ‘q‘))
visibility_of_element_located               节点可见,传入定位元组
visibility_of                               节点对象可见,传入节点对象
presence_of_all_elements_located            所有节点加载出来
text_to_be_present_in_element               某个节点文本包含某文字
text_to_be_present_in_element_value         某个节点值包含某文字
text_to_be_available_amd_switch_to_it       加载并切换
invisibility_of_element_located             节点不可见
element_to_be_clickable                     节点可点击
staleness_of                                判断节点是否在DOM,可用于判断页面是否已经刷新
element_to_be_selected                      节点可选择,传入节点对象
element_located_to_be_selected              节点可选择,传入节点定位元组
element_selection_state_to_be               传入节点对象及状态,相等返回True
element_located_selection_state_to_be       传入定位元组及状态,相等返回True
alert_is_present                            是否出现警告
‘‘‘

 

11. 前进和后退

## 前进和后退
from selenium import webdriver
import time

browser = webdriver.Chrome()
browser.get(https://www.baidu.com)
browser.get(https://www.taobao.com)
browser.get(https://www.zhihu.com)
browser.get(https://www.mi.com)
browser.back()
browser.back()
browser.forward()
time.sleep(2)

browser.close()

 

12. Cookies操作,获取、添加、删除等 

## Cookies操作,获取、添加、删除
from selenium import webdriver

browser = webdriver.Chrome()
browser.get(https://www.taobao.com)
print(len(browser.get_cookies()), browser.get_cookies())
browser.add_cookie({name: name, domain: .taobao.com, value: dfjld})
print(len(browser.get_cookies()), browser.get_cookies())
browser.delete_all_cookies()
print(len(browser.get_cookies()), browser.get_cookies())

browser.close()

 

13. 选项卡操作

## 选项卡处理
import time
from selenium import webdriver

browser = webdriver.Chrome()
browser.get(https://www.baidu.com)
# 新建选项卡
browser.execute_script(window.open())
print(browser.window_handles)
# 切换选项卡
browser.switch_to_window(browser.window_handles[1])
browser.get(https://www.taobao.com)
print(browser.current_url)
browser.switch_to.window(browser.window_handles[0])
print(browser.current_url)

browser.close()

 

14. 异常处理

## 异常处理
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException, TimeoutException

browser = webdriver.Chrome()
try:
    browser.get(https://www.taobao.com)
except TimeoutException:
    print(TIME OUT...)

try:
    browser.find_element_by_id(qdfd)
except NoSuchElementException:
    print(NO ELEMENT...)

finally:
    browser.close()

 

15. selenium爬取jd商品信息实例代码

技术图片
### selenium爬取jd商品信息
### Author: dmr
from pyquery import PyQuery as pq
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.common.exceptions import StaleElementReferenceException
from urllib.parse import quote
import requests, time, pymongo

def get_source_page(browser, keyword, page):
    ‘‘‘
    判断当前页面是否加载完成并返回加载完成页面源码
    :param page:页码
    :return:页面源码
    ‘‘‘

    wait = WebDriverWait(browser, 10)
    print(正在爬取第 %d 页 % page)
    try:
        url = https://search.jd.com/Search?enc=utf-8&keyword= + quote(keyword)
        browser.get(url)
        # 拉到浏览器页面底部,获取当前页面所有的商品信息,防止操作过程中页面节点变化导致操作失败
        browser.execute_script(window.scrollTo(0, document.body.scrollHeight))
        time.sleep(2)
        # wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ‘#J_goodsList li.gl-item > div.gl-i-wrap‘)))
        # 当page大于1时,进行页面跳转
        if page > 1:
            # 获取当前跳转页面节点
            page_input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, #J_bottomPage .p-skip > input)))
            # 获取跳转页面按键节点
            submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, #J_bottomPage .p-skip > a)))
            page_input.clear()
            page_input.send_keys(str(page))
            submit.click()
        # 确保已完成页面跳转
        wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, #J_bottomPage .p-num > a.curr), str(page)))
        # 确保页面商品信息加载完成
        wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, #J_goodsList li.gl-item > div.gl-i-wrap)))
        print(第 %s 页面加载完成,可以进行获取源码... % str(page))

        return browser.page_source

    except TimeoutException or StaleElementReferenceException:
        # 如果出现错误,继续尝试爬取
        print(出现错误,正在继续尝试。。。)
        get_source_page(browser, keyword, page)

def get_data(html):
    ‘‘‘
    提取网页源代码并进行解析获取想要爬取的内容
    :return:
    ‘‘‘

    doc = pq(html)
    items = doc(#J_goodsList li > .gl-i-wrap).items()
    for item in items:
        yield {
            img: item(.p-img img).attr.src if item(.p-img img).attr.src else item(.p-img img).attr(data-lazy-img),
            price: item(.p-price strong i).text(),
            title: item(.p-name.p-name-type-2 em).text(),
            commit: item(.p-commit strong a).text(),
            shop: item(.p-shop span a).text(),
            icons: item(.p-icons i).text(),
        }

def save_to_mongodb(collection, data):
    for item in data:
        try:
            collection.insert_one(item)
            print("插入数据成功,数据内容为:", item)
        except:
            print("插入数据内容失败,数据内容为:", item)

def main(browser, keyword, offset):
    html = get_source_page(browser, keyword, offset)
    if html:
        data = get_data(html)
        # 建立连接对象
        client = pymongo.MongoClient(host=10.0.0.100, port=27017)
        # 指定数据库,如无则创建
        db = client.jd
        # 指定集合,如无则创建
        collection = db[keyword]
        # 保存到mongodb中
        save_to_mongodb(collection, data)
    else:
        print(第%s页的页面源码加载有误,页面源码为:%s % (offset, html))


if __name__ == __main__:
    keyword = input("请输入商品信息关键字:")
    browser = webdriver.Chrome()
    for page in range(1, 101):
        main(browser, keyword, page)

    browser.close()
View Code

 

 

       更多用法参见官方:http://selenium-python.readthedocs.io/api.html

 

以上是关于爬虫动态渲染页面爬取之selenium驱动chrome浏览器的使用的主要内容,如果未能解决你的问题,请参考以下文章

PHP 爬虫体验 - 使用PHP + puppeteer爬取js动态渲染的页面内容

python动态渲染页面爬取Selenium的具体使用

python动态渲染页面爬取Selenium的具体使用

python动态渲染页面爬取Selenium的具体使用

爬虫(十七):Scrapy框架 对接selenium爬取京东商品数据

python--Selenium(动态渲染页面爬取)