seleinum

Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,可以按指定的命令自动操作,不同是Selenium 可以直接运行在浏览器上,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器)。 Selenium 可以根据我们的指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生。
Selenium 自己不带浏览器,不支持浏览器的功能,它需要与第三方浏览器结合在一起才能使用。但是我们有时候需要让它内嵌在代码中运行,所以我们可以用一个叫 PhantomJS 的工具代替真实的浏览器。
安装

pip3 install selenium

selenium不自带浏览器,所以我们需要第三方浏览器
驱动下载:

谷歌驱动(chromedriver)下载地址: http://chromedriver.storage.googleapis.com/index.html
火狐驱动下载路径(GeckoDriver):https://github.com/mozilla/geckodriver/releases(2.3.8是最新的,下载的驱动版本一定要支持你当前的浏览器版本)

页面的相关操作:

获取id标签值

element = driver.find_element_by_id("passwd-id")

获取name标签值

element = driver.find_element_by_name("user-name")

获取标签名值

element = driver.find_elements_by_tag_name("input")

也可以通过XPath来匹配

element=driver.find_element_by_xpath("//input[@id='passwd-id']")

页面前进和后退

操作页面的前进和后退功能:
driver.forward() #前进
driver.back() # 后退

添加cookies

driver.add_cookie(cookie_dict)

删除Cookies,用法如下

  • 删除一个特定的cookie
    driver.delete_cookie("CookieName")
  • 删除所有cookie
    driver.delete_all_cookies()

设置无头浏览器

opt = webdriver.ChromeOptions()
opt.set_headless()

设置代理

opt = webdriver.ChromeOptions()
opt.add_argument("--proxy-server=http://118.20.16.82:9999")

代码:

#  pip3 install selenium
# selenium不自带浏览器,必须跟第三方的浏览器配合使用

from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys

#如何设置屋头浏览器
opt = webdriver.ChromeOptions()
#设置为无头浏览器()
# opt.set_headless()
# 设置代理
opt.add_argument("--proxy-server=http://202.20.16.82:10152")

#创建一个浏览器的驱动
chrome_driver = webdriver.Chrome(
    executable_path='/home/ljh/桌面/driver/chromedriver',
)

chrome_driver.get('https://www.baidu.com/')

#chrome_driver.save_screenshot('baidu.png')

#PhantomJS屋头浏览器
# phantom_js = webdriver.PhantomJS(executable_path='/home/ljh/桌面/driver/phantomjs')
#
# phantom_js.get('https://www.baidu.com/')
#
# phantom_js.save_screenshot('baidu2.png')

#获取页面源码(这时候获取的页面源码是经过浏览器渲染之后的结果)
#豆瓣的例子
#chrome_driver.get('https://movie.douban.com/subject_search?search_text=%E7%94%B5%E5%BD%B1&cat=1002')
html_data = chrome_driver.page_source
#获取cookies
cookies = chrome_driver.get_cookies()
print(cookies)
#可以获取当前请求的url
cur_url = chrome_driver.current_url

#模拟用户操作
#以百度为例
#再搜搜兰中输入文字
chrome_driver.find_element_by_id('kw').send_keys('中国我的国')
#点击按钮
chrome_driver.find_element_by_id('su').click()

# time.sleep(3)
# 隐士等待:当我们寻找节点的时候,有时候页面可能没有加载出来,
# 设置隐士等待,没找到的话会等一会继续寻找,如果在设定的时间内还没有找到
# 会出现异常错误
chrome_driver.implicitly_wait(10)

#显示等待

#点击下一页
# chrome_driver.find_element_by_class_name('n').click()
#根据文字寻找
chrome_driver.find_element_by_link_text('下一页>').click()

# with open('page.html','w') as file:
#     file.write(html_data)

chrome_driver.find_element_by_id('kw').clear()
chrome_driver.find_element_by_id('kw').send_keys('我的媳妇是谁')
#Keys.RETURN模拟键盘的回车操作
chrome_driver.find_element_by_id('su').send_keys(Keys.RETURN)

"""
#通关节点的name属性查找对应的节点
chrome_driver.find_element_by_name()
#通过节点的class_name找到对应的节点
chrome_driver.find_element_by_class_name()
#通过css选择器查找对应的节点
chrome_driver.find_element_by_css_selector()
#通过连接所在标签的部分文字找到对应的节点
chrome_driver.find_element_by_partial_link_text()
#通过xpath路径找对对应的节点
chrome_driver.find_element_by_xpath()
.....
"""

#获取节点的属性get_attribute('属性的名称')
print(chrome_driver.find_element_by_id('su').get_attribute('value'))
#获取节点的文本.text
print(chrome_driver.find_element_by_class_name('n').text)

#回退
chrome_driver.back()
#前进
chrome_driver.forward()

#关闭浏览器(只有一个界面会退出浏览器,多个界面时只表示关闭当前界面)
chrome_driver.close()

#退出浏览器
chrome_driver.quit()

页面等待

注意:这是非常重要的一部分!! 现在的网页越来越多采用了 Ajax 技术,这样程序便不能确定何时某个元素完全加载出来了。如果实际页面等待时间过长导致某个dom元素还没出来,但是你的代码直接使用了这个WebElement,那么就会抛出NullPointer的异常。 为了避免这种元素定位困难而且会提高产生 ElementNotVisibleException 的概率。所以 Selenium 提供了两种等待方式,一种是隐式等待,一种是显式等待。
隐式等待是等待特定的时间,显式等待是指定某一条件直到这个条件成立时继续执行。

隐式等待

from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10) # seconds
driver.get("http://www.xxxxx.com/loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")

显式等待

显式等待指定某个条件,然后设置最长等待时间。如果在这个时间还没有找到元素,那么便会抛出异常了。 程序默认会 0.5s 调用一次来查看元素是否已经生成,如果本来元素就是存在的,那么会立即返回。

from selenium import webdriver
from selenium.webdriver.common.by import By
# WebDriverWait 库,负责循环等待
from selenium.webdriver.support.ui import WebDriverWait
# expected_conditions 类,负责条件出发
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get("http://www.xxxxx.com/loading")
try:
    ##### 会在这里等待,如果10秒内 id="myDynamicElement"的标签出现
    则返回,如果不出现则报异常
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located(
            (By.ID, "myDynamicElement")
            )
    )
finally:
    driver.quit()

异常处理

请求超时异常处理

from selenium.common.exceptions import TimeoutException

try:
   brower.get(url)
except TimeoutException:
   print('Time out')

找不到标签的异常处理

from selenium.common.exceptions import NoSuchElementException

try:
    brower.find_element_by_id('').click()
    print('有标签')
except NoSuchElementException:
    print('没有这个标签')    

selenium动态页面模拟点击案例:
爬取斗鱼直播平台的所有房间信息:

from selenium import webdriver
import json
import time
class Douyu:
    # 1.发送首页的请求
    def __init__(self):
        self.driver = webdriver.PhantomJS()
        self.driver.get("https://www.douyu.com/directory/all") #请求首页

    #获取没页面内容
    def get_content(self):
        time.sleep(3) #每次发送完请求等待三秒,等待页面加载完成
        li_list = self.driver.find_elements_by_xpath('//ul[@id="live-list-contentbox"]/li')
        contents = []
        for i in li_list: #遍历房间列表
            item = {}
            item["img"] = i.find_element_by_xpath("./a//img").get_attribute("src") #获取房间图片
            item["title"] = i.find_element_by_xpath("./a").get_attribute("title") #获取房间名字
            item["category"] = i.find_element_by_xpath("./a/div[@class='mes']/div/span").text #获取房间分类
            item["name"] = i.find_element_by_xpath("./a/div[@class='mes']/p/span[1]").text #获取主播名字
            item["watch_num"] = i.find_element_by_xpath("./a/div[@class='mes']/p/span[2]").text #获取观看人数
            print(item)
            contents.append(item)
        return contents
    #保存本地
    def save_content(self,contents):
        f = open("douyu.txt","a")
        for content in contents:
            json.dump(content,f,ensure_ascii=False,indent=2)
            f.write("\n")
        f.close()

    def run(self):
        #1.发送首页的请求
        #2.获取第一页的信息
        contents = self.get_content()
            #保存内容
        self.save_content(contents)
        #3.循环  点击下一页按钮,知道下一页对应的class名字不再是"shark-pager-next"
        while self.driver.find_element_by_class_name("shark-pager-next"): #判断有没有下一页
            #点击下一页的按钮
            self.driver.find_element_by_class_name("shark-pager-next").click() #
            # 4.继续获取下一页的内容
            contents = self.get_content()
            #4.1.保存内容
            self.save_content(contents)

if __name__ == "__main__":
    douyu = Douyu()
    douyu.run()
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容