任务1:Selenium基本操作
from selenium import webdriver # 通用选择 from selenium.webdriver.common.by import By # 动作 from selenium.webdriver import ActionChains from selenium.webdriver.common.keys import Keys # 抛出异常 from selenium.webdriver.support import expected_conditions as EC # 异常处理 超时和为发现元素 from selenium.common.exceptions import TimeoutException,NoSuchElementException from selenium.webdriver.support.wait import WebDriverWait import time # 申明驱动浏览器对象,支持Android,BlackBerry等手机端浏览器 browser = webdriver.Chrome() # browser = webdriver.PhantomJS # 设置浏览器窗口大小 browser.set_window_size(1400, 900) try: # 必须输入完整URL,直接输入www.baidu.com不行 # 打开URL为XXX的网页 browser.get('http://www.baidu.com') # 开启新选项卡(开启新窗口) browser.execute_script('window.open()') # 打印当前所有句柄 print(browser.window_handles) # 切换句柄(选项卡) browser.switch_to.window(browser.window_handles[1]) # switch_to_window被switch_to.window代替,用法一致 # browser.switch_to_window(browser.window_handles[1]) # 在新的选项卡中打开XXX网页 browser.get('https://www.taobao.com/') # 切回第一个选项卡 browser.switch_to.window(browser.window_handles[0]) # 直接通过id查找 input1 = browser.find_element_by_id('kw') # 通过css选择器查找,直接在检查中Cope→Cope selector input2 = browser.find_element_by_css_selector('#kw') # 通过Xpath选择器查找,可以直接在Cope→Cope xpath input3 = browser.find_element_by_xpath('//*[@id="kw"]') # 通用选择,需要先引入By from selenium.webdriver.common.by import By # By后面可以跟ID,CSS_SELECTOR,XPATH等,第二个参数就上面括号内的参数 input4 = browser.find_element(By.ID, 'kw') # 多个节点也是按照上面进行查找,只是element后面加个s,find_elements time.sleep(1) # 输入框键入'xx' input1.send_keys('美女') # 清空文字 # input1.clear() # 直接敲击键盘Enter键 # input.send_keys(Keys.ENTER) # 通过找到id为su的搜索键,鼠标单击 browser.find_element_by_id('su').click() time.sleep(1) browser.execute_script('window.open()') browser.switch_to.window(browser.window_handles[2]) browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable') # 切换到子Frame 通常节点名字叫iframe browser.switch_to.frame('iframeResult') # 切换回父Frame # browser.switch_to.parent_frame() # 找到2个标签 source = browser.find_element(By.CSS_SELECTOR, '#draggable') target = browser.find_element(By.CSS_SELECTOR, '#droppable') # 动作链必须先引入 from selenium.webdriver import ActionChains action = ActionChains(browser) # 执行拖拽动作 # action.drag_and_drop(source, target) # 有action 必须有perform方法 action.perform() browser.execute_script('window.open()') browser.switch_to.window(browser.window_handles[3]) browser.get('https://www.taobao.com/') browser.execute_script('window.scrollTo(0,document.body.scrollHeight)') logo = browser.find_element(By.CSS_SELECTOR,'#q') print(logo) # 获取输入框属性值 print(logo.get_attribute('aria-label')) # 获取搜索按钮的文字 input5 = browser.find_element(By.XPATH,'//*[@id="J_TSearchForm"]/div[1]/button') # 文字 print(input5.text) # 标签名 print(input5.tag_name) # id print(input5.id) # 在页面中的相对位置 print(input5.location) # 节点大小 print(input5.size) # 显式等待(等待直到标签出现或超过最大等待时间) # 设置最大等待时间是10秒 # 报错先引入 from selenium.webdriver.support import expected_conditions as EC wait = WebDriverWait(browser,10) # 等待直到id为q的标签出现 input6 = wait.until(EC.presence_of_element_located((By.ID,'q'))) # 等待直到按钮可以被点击 input7 = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.btn-search'))) browser.switch_to.window(browser.window_handles[0]) # 前进和后退 browser.back() time.sleep(3) browser.forward() # 增加一个cookie browser.add_cookie({'name':'xiaohei','age':'123'}) # 删除 cookie # browser.delete_cookie() # browser.delete_all_cookies() # 当前URL print(browser.current_url) # Cookie print(browser.get_cookies()) # 源代码 # print(browser.page_source) except NoSuchElementException: print("No Element") # 一定会做的事情 finally: # 关闭浏览器 pass # browser.close()
任务2:unittest测试框架(斗鱼的例子)
''' Ajax含有很多加密参数,我们无法直接进行爬取,只能借助Selenium ''' #!/usr/bin/env python # -*- coding:utf-8 -*- import unittest from selenium import webdriver from bs4 import BeautifulSoup as bs import time class douyu(unittest.TestCase): # 初始化方法,必须是setUp() def setUp(self): # self.driver = webdriver.Chrome() self.driver = webdriver.PhantomJS() self.num = 0 self.count = 0 # 测试方法必须有test字样开头 def testDouyu(self): self.driver.get("https://www.douyu.com/directory/all") while True: soup = bs(self.driver.page_source, "lxml") # 房间名, 返回列表 names = soup.find_all("h3", {"class": "DyListCover-intro"}) # 直播间热度, 返回列表 numbers = soup.find_all("span", {"class": "DyListCover-hot"}) for name, number in zip(names, numbers): self.num += 1 print( u"直播间热度: -" + number.get_text().strip() + u"-\t房间名: " + name.get_text().strip() + u'-\t直播数量' + str( self.num)) result = u"直播间热度: -" + number.get_text().strip() + u"-\t房间名: " + name.get_text().strip() + u'-\t直播数量' + str( self.num) with open('123.txt','a',encoding='utf-8') as f: f.write(result) # self.count += int(number.get_text().strip()) # 如果在页面源码里找到"下一页"为隐藏的标签,就退出循环 if self.driver.page_source.find("dy-Pagination-disabled dy-Pagination-next") != -1: break # 一直点击下一页 self.driver.find_element_by_class_name("dy-Pagination-next").click() time.sleep(1) # 测试结束执行的方法 def tearDown(self): # 退出PhantomJS()浏览器 print("当前网站直播人数" + str(self.num)) print("当前网站总热度" + str(self.count)) self.driver.quit() if __name__ == "__main__": # 启动测试模块 unittest.main()