官方文档:http://selenium-python-docs-zh.readthedocs.io/zh_CN/latest/
模拟浏览器中网页的跳转,输入,点击,下拉
-安装:
pip install selenium
chromedriver : http://chromedriver.storage.googleapis.com/index.html
(谷歌若是最新版的就安装v2.36)
声明浏览器与访问页面
注:selenium支持很多浏览器,一般在测试阶段使用Chrome(需要下载Chromedriver,并配置环境变量);在运行阶段使用PhantomJS(需要配置环境变量),该浏览器可以无界面测试,网络截屏,页面自动化。
from selenium import webdriver
driver=webdriver.Chrome() #声明浏览器对象
driver.get("http://www.baidu.com") #通过浏览器打开百度页面
print(driver.page_source) #得到网页html信息
driver.close() #关闭浏览器
导航
-页面交互(向文本框和文本域输入内容)
#获取一个元素
element=driver.find_element_by_id("pass_id")
#通过send_keys方法输入文本信息
element.send_keys("some text")
#文本内容不会自动清除,因此避免干扰下次的操作需要清楚
element.clear()
-填充表单(下拉选项框,并选中)
#选中特定的选项---select方法
from selenium.webdriver.support.ui import Select
select = Select(driver.find_element_by_name('name'))
select.selct_by_index(index)
select.select_by_visible_text("text")
select.select_by_value(value)
#取消选中项--select.deselect_all方法
select = Select(driver.find_element_by_id('id'))
select.deselect_all()
#提交表单 .click方法
# 假设存在一个提交按钮的ID 为"submit"
driver.find_element_by_id("submit").click()
-拖拽(将一个元素拖拽指定的距离或到另一个元素上)
#ActionChains方法
from selenium.webdriver import ActionChains
element = driver.find_element_by_name("source")
target = driver.find_element_by_name("target")
action_chains = ActionChains(driver)
action_chains.drag_and_drop(element,target).perform()
-在窗口和框架间移动
#将框架切换到另一个框架
driver.switch_to_frame("frameName")
#回到父框架
driver.switch_to_default_content()
-弹出对话框
#获取对话框元素
alert=driver.switch_to_alert()
-Cookie
# 进入一个网页页面
driver.get("http://example.com")
# 设置cookie字典键值对
cookie = {'name':'foo','value':'bar'}
#添加cookie到浏览器对象中
driver.add_cookie(cookie)
#得到浏览对象中的所有cookie值
driver.get_cookies()
元素定位
#针对单个元素
find_element_by_id #根据id定位
find_element_by_name #根据name定位
find_element_by_xpath #根据XPath定位
find_element_by_link_text #根据用链接文本定位超链接
find_element_by_tag_name #根据标签名(Tag name)定位
find_element_by_class_name #根据class定位
find_element_by_css_selector #根据css选择器定位
#针对多个元素--返回一个list
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
#两个私有方法 find_element和find_elements
from selenium.webdriver.common.by import By
#driver是一个浏览器对象
driver.find_element(By.XPATH,"//div[@class='section']//p/text()")
----By的属性
ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag_name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"
#获取元素属性,文本值,ID,位置,标签名
-element.get_attribute("attrs_name")
-element.text
-element.id
-element.location
-element.tag_name
-element.size
注意:如果没有元素匹配,将会抛出NoSuchElementException
异步(等待,给页面的加载执行提供了一些时间间隔)
-显示等待
#会让webdriver在更深一步的执行前等待一个确定的条件触发
相对与time.sleep()等待的时间,显示等待则是让编写的代码只等待需要的时间(WebDriverWait结合ExpectedCondition实现)
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
driver=webdriver.Chrome()
driver.get("http://example.com")
try:
element=WebDriverWait(driver,10).until(
EC.presence_of_element_located((By.ID,"id_name"))
)
finally:
driver.quit()
注意:
触发条件(expected_conditions)
title_is
title_contains
presence_of_element_located
visibility_of_element_located
visibility_of
presence_of_all_elements_located
text_to_be_present_in_element
text_to_be_present_in_element_value
frame_to_be_available_and_switch_to_it
invisibility_of_element_located
element_to_be_clickable # it is Displayed and Enabled.
staleness_of
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
alert_is_present
-隐式等待
#会让webdriver试图定位元素的时候让DOM进行指定次数的轮询,默认设置是0次
from selenium import webdriver
driver=webdriver.Chrome()
driver.implicitly_wait(10) #单位是秒
driver.get("http://example.com")
myDynamicElement=driver.find_element_by_id("id_name")
异常处理
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
browser = webdriver.Chrome()
try:
browser.get('https://www.baidu.com')
except TimeoutException:
print('Time Out')
try:
browser.find_element_by_id('hello')
except NoSuchElementException:
print('No Element')
finally:
browser.close()
实例—爬去淘宝美食
import re
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from lxml import etree
driver=webdriver.Chrome() #建立浏览器对象
wait=WebDriverWait(driver,10) #创建显示wait对象
#搜索页面
def search():
driver.get("https://www.taobao.com")
try:
#获取文本框元素---注意触发条件的第一参数是一个元组
input=wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#q'))
)
#获取提交按钮元素
submit=wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_TSearchForm > div.search-button > button'))
)
#输入搜素关键字
input.send_keys('美食')
#点击提交
submit.click()
#获取底部总页面元素---主要是获取总共的页面数量
total=wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.total'))
)
#解析第一页的html信息
get_contents()
return total.text
except TimeoutException:
return search()
#其他页信息判断
def next_page(page_number):
try:
#获取元素
input = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.form > input'))
)
submit = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, '#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit'))
)
#清楚文本框--必须要有
input.clear()
#输入页数
input.send_keys(page_number)
submit.click()
#判断是否进入下一页---这里采用下一页的高亮按钮是否出现作为加载完成的判断依据
wait.until(
EC.text_to_be_present_in_element((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > ul > li.item.active'),str(page_number)))
#获取该页的html信息
get_contents()
except TimeoutException:
return next_page(page_number)
def get_contents():
#加载判断条件
wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, '#main'))
)
html_str=driver.page_source
html=etree.HTML(html_str)
#分组
div_list=html.xpath("//div[@data-category='auctions']")
content_list=[]
#迭代获取每一项
for div in div_list:
item = {}
s=str(div.xpath(".//div[@class='pic']/a[@class='pic-link J_ClickStat J_ItemPicA']/img/@src"))
item['img'] = "https:" +s
content_list.append(item)
print(content_list)
def main():
total=search()
total=int(re.compile('(\d+)').search(total).group(1))
for i in range(2,total+1):
next_page(i)
if __name__ == '__main__':
main()
这篇博客介绍了如何利用Selenium库解决JavaScript渲染问题,包括声明浏览器与访问页面、导航、元素定位、异步等待以及异常处理。还提供了一个实例,展示了如何爬取淘宝美食页面。
4554

被折叠的 条评论
为什么被折叠?



