1.正则表达式
'.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$' 匹配字符结尾, 若指定flags MULTILINE ,re.search('foo.$','foo1\nfoo2\n',re.MULTILINE).group() 会匹配到foo1
'*' 匹配*号前的字符0次或多次, re.search('a*','aaaabac') 结果'aaaa'
'+' 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?' 匹配前一个字符1次或0次 ,re.search('b?','alex').group() 匹配b 0次
'{m}' 匹配前一个字符m次 ,re.search('b{3}','alexbbbs').group() 匹配到'bbb'
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配, re.search("(abc){2}a(123|45)", "abcabca456c").group() 结果为'abcabca45'
'[...]' 用来表示一组字符,单独列出,比如匹配[amk]匹配a,m或k
'\A' 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的,相当于re.match('abc',"alexabc") 或^
'\Z' 匹配字符结尾,同$
'\d' 匹配数字0-9
'\D' 匹配非数字
'\w' 匹配[A-Za-z0-9],还包括下划线‘_’
'\W' 匹配非[A-Za-z0-9]
's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
'(.*?)' 贪婪匹配,用来获取目标字符
'.*?' 非贪婪匹配,用来替换任意非目标字符
常用方法:
re.match()
re.match()方法会从字符串的起始位置开始匹配正则表达式,如果匹配,就返回匹配成功的结果,一旦开头不匹配,直接返回None,整个匹配失败
re.search()
re.search():扫描整个字符串,然后返回第一个成功匹配的结果
re.findall()
re.findall():把所有匹配到的字符放到以列表中的元素返回,返回的列表中的每一个元素都是元组类型(元组型列表)
re.sub()
re.sub(‘a’,‘b’,content) ,即在content中,用b替换a的内容
re.compile()
compile(‘编译字符’,re.S/I/M)方法将正则表达式字符串编译成正则表达式对象,以便在后面的匹配中复用
修饰符
修饰符 | 描述 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.M | 多行匹配 |
re.S | 使.匹配包括换行在内的所有字符 |
2.xpath
1.导入相关库包
from lxml import etree
2.初始化
html = etree.HTML(response.text)
3.常用规则
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点 |
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档的节点,而不考虑它们的位置 |
. | 选取当前节点 |
… | 选取当前节点的父节点 |
@ | 选取属性 |
路径表达式 | 描述 |
---|---|
bookstore | 选取 bookstore 元素的所有子节点 |
/bookstore | 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素 |
//book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
//@lang | 选取名为 lang 的所有属性。 |
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。索引默认从1开始 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()❤️] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang=’eng’] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
3.pyquery
导入相关库包
from pyquery import PyQuery as pq
初始化工作
doc = pq(html)字符串初始化
doc = pq(url)URL初始化
doc = pq(filename="")文件初始化
print(doc(‘li’))
css选择器
表达式 | 说明 |
---|---|
id选择器 | 使用# |
class选择器 | 使用. |
标签选择器 | 直接使用标签,什么都不加 |
* | 选择所有元素 |
p | 选择所有p标签 |
div,p | 选择所有的div和p标签(并集) |
div p | 选择div下的所有p标签(子集) |
pyquery获取信息(跟jQuery用法一样)
1.获取属性值:变量名.attr(属性名) 或者 变量名.attr.属性名
2.获取文本内容:变量名.text()
3.获取html: 变量名.html()
4.找寻某一特定标签:变量名.find(标签名).eq(n) n从0开始,表示find某标签,并选择第n个目标值
4.Selenium库学习
动态渲染页面不仅仅涉及到Ajax技术,绝大多数的网页是通过Javascript计算生成新页面的,比如说百度Echarts,淘宝,中国青年网。。。
4.1基本库导入
from selenium import webdrive
from selenium.webdrive.common.by import By
# 若想要模拟键盘,就需要导入keys()类
from selenium.webdrive.common.keys import Keys
# 等待条件类
from selenium.webdrive.support import expected_conditions as EC
# 等待条件
from selenium.webdrive.support.wait import WebDriverWait
# 监听鼠标事件,声明动作链
from selenium.webdrive import ActionChains
# 导入下拉选择框Select类
from selenium.webdriver.support.select import Select
4.2 声明浏览器对象
browser = webdriver.Chrome()/Firefox()/PhantomJS() 等等
4.3 访问目标页面
# 访问目标网址
browser.get("https://www.taobao.com")
# 打印页面源代码
print(browser.page_source)
# 关闭浏览器
browser.close()
4.4 获取单个节点的方法
语法:find_element(By.xx,“XXX”)或者是find_elements(By.xx,“XXX”)
一般常用的是(By.ID,id_name),(By.XPath,xpath_path),(By.CSS_SELECTOR,css_selector_path)
4.5 节点交互
Selenium可以驱动浏览器执行一些列操作,可以模仿一些列简单的人的动作:
nodeName.send_keys(“content”):输入目标节点框文字
nodeName.clear():清空目标节点框文字
nodeName.click():点击目标节点
控制浏览器的操作方法 | 说明 |
---|---|
click() | 点击目标节点 |
set_window_size() | 设置浏览器的大小 |
back() | 控制浏览器后退 |
forward() | 控制浏览器前进 |
refresh() | 刷新当前页面 |
clear() | 清除文本 |
send_keys (value) | 模拟按键输入 |
close() | 关闭浏览器 |
quit() | 关闭所有窗口 |
submit() | 用于提交表单 |
get_attribute(name) | 获取元素属性值 |
is_displayed() | 设置该元素是否用户可见 |
size | 返回元素的尺寸 |
location | 返回元素在浏览器中的位置,以字典的形式返回 |
text | 获取元素的文本 |
2019-12-30:新增关于location和size方法的说明
先看示例源代码:
# 显示等待图片节点加载出来
img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_canvas_img')))
time.sleep(2)
location = img.location
size = img.size
这里用了显示等待获取到了我要识别的滑动验证码图片对象,接下来调用该对象的location属性和size属性。
location属性可以返回该图片对象(既这张图片)在浏览器中的位置(坐标轴是以屏幕左上角为原点,x轴向右递增,y轴像下递增),以字典的形式返回
{"x":30,
"y":30
}
# 这里我们假设图片的位置是(30,30)
size属性同样返回一个字典,size属性是图片对象的高度,宽度。
{
"height":30,
"width":30
}
4.6 鼠标事件
在WebDriver中,将这些关于鼠标操作的方法封装在 ActionChains 类提供。
鼠标监听方法 | 说明 |
---|---|
ActionChains(driver) | 构造ActionChains对象 |
move_to_element(above) | 执行鼠标悬停操作 |
context_click() | 右击 |
double_click() | 双击 |
drag_and_drop() | 拖动 |
move_to_element(above) | 执行鼠标悬停操作 |
context_click() | 用于模拟鼠标右键操作, 在调用时需要指定元素定位 |
perform() | 执行所有 ActionChains 中存储的行为,可以理解成是对整个操作的提交动作 |
————————————————
4.7 多表单切换,点击详情
在Web应用中经常会遇到frame/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于frame/iframe表单内嵌页面上的元素无法直接定位。这时就需要通过switch_to.frame()方法将当前定位的主体切换为frame/iframe表单的内嵌页面中。
鼠标监听方法 | 说明 |
---|---|
switch_to.frame() | 将当前定位的主体切换为frame/iframe表单的内嵌页面中 |
switch_to.default_content() | 跳回最外层的页面 |
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.126.com")
# 切换到id为x-URS-iframe的iframe表单
driver.switch_to.frame('x-URS-iframe')
driver.find_element_by_name("email").clear()
driver.find_element_by_name("email").send_keys("username")
driver.find_element_by_name("password").clear()
driver.find_element_by_name("password").send_keys("password")
driver.find_element_by_id("dologin").click()
driver.switch_to.default_content()
driver.quit()
switch_to.frame() 默认可以直接取表单的id 或name属性。如果iframe没有可用的id和name属性,则可以通过下面的方式进行定位。
先通过xpth定位到iframe
xf = driver.find_element_by_xpath(’//*[@id=“x-URS-iframe”]’)
再将定位对象传给switch_to.frame()方法
driver.switch_to.frame(xf)
driver.switch_to.parent_frame()
4.8 设置元素等待
元素等待分为显示等待(推荐:显式等待使WebdDriver等待某个条件成立时继续执行,否则在达到最大时长时抛出超时异常(TimeoutException))与隐式等待
<font color=>selenium.webdriver.support.ui 和selenium.webdriver.support.wait都是用来做显式等待的,但两者没有任何一丢丢的区别,将ui换成了wait,这样更直接易懂。
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
# 导入时间等待库文件
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
# 最长超时时间为10s,检测间隔为0.5s
wait = WebDriverWait(driver,10,0.5)
element = wait.until(
# 等待节点出现的含义
EC.presence_of_element_located((By.ID, "kw"))
)
# 输入文本
element.send_keys('selenium')
time.sleep(10)
# 浏览器退出
driver.quit()
2020-1-11 新增:
4.9 下拉框选择操作
导入选择下拉框Select类,使用该类处理下拉框操作
方法:select_by_value(“选择值”):相当于我们使用鼠标选择下拉框的值
from selenium import webdriver
from selenium.webdriver.support.select import Select
from time import sleep
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
#1.鼠标悬停至“设置”链接
driver.find_element_by_link_text('设置').click()
sleep(1)
#2.打开搜索设置
driver.find_element_by_link_text("搜索设置").click()
sleep(2)
#3.搜索结果显示条数
sel = driver.find_element_by_xpath("//select[@id='nr']")
Select(sel).select_by_value('50') # 显示50条
sleep(3)
driver.quit()
4.10 警告框处理
在WebDriver中处理JavaScript所生成的alert、confirm以及prompt十分简单,具体做法是使用 switch_to.alert 方法定位到 alert/confirm/prompt,然后使用text/accept/dismiss/ send_keys等方法进行操作。
鼠标监听方法 | 说明 |
---|---|
text | 返回 alert/confirm/prompt 中的文字信息 |
accept() | 接受现有警告框 |
dismiss() | 解散现有警告框 |
send_keys(keysToSend) | 发送文本至警告框。keysToSend:将文本发送至警告框 |