【python爬虫笔记】 lxml requests selenium模块

目录

Python lxml 模块

lxml.etree

XPath

lxml 扩展知识

Python requests 模块

requests.get() 方法

响应对象的属性与方法

会话对象

SSL 证书验证,客户端证书,CA 证书

代理

提高场景

Python selenium 入手篇

selenium 安装

编写第一个 selenium 案例

webdriver 对浏览器基本操作

网页元素定位

通过 ID 与 name 进行定位

通过 XPath 表达式进行定位

selenium 入手篇扩展知识

安装 PhanomJS

使用无头浏览器 


Python lxml 模块

lxml 库是一款 Python 数据解析库,参考重要文档在 lxml - Processing XML and HTML with Python

lxml.etree

在解析数据的时候,大量的代码都是基于 Element 对象的 API 实现。

在爬虫代码采集过程中,通过 etree.HTML 直接将字符串实例化为 element 对象。

import requests
from lxml import etree

res = requests.get("http://www.jsons.cn/zt/")

html = res.text

root_element = etree.HTML(html)

print(root_element)#<Element html at 0x3310508>

print(root_element.tag)#html

其中需要注意的是 Element 后面的 html,该字符串表示对象的标签名为 html,如果使用下述代码:

print(root_element[0])

上述内容得到的是  <Element head at 0x1913771e800>,即head标签,同样的操作可以使用子元素获取。

print("*"*100)
for child in root_element:
    print(child.tag)#head  表示在 html 标签中,只包含head 标签 

也可以通过 etree.tostring(element对象) 直接将该对象转换为字符串进行输出。

for child in root_element:
    for item in child:
        print(item.tag)
        print(etree.tostring(item))

XPath

lxml 库可以配合其他的解析引擎进行工作,首次接触的就是 XPath

在爬虫代码编写中,直接使用 html.xpath("xpath表达式") 即可获取目标数据,例如获取网页 title。

print(root_element.xpath('//title'))

获取网页所有文本:

print(root_element.xpath('string()'))

获取到 element 对象之后,可调用 text 属性,获取对应文本,在使用的时候,需要注意使用 XPath 获取到的 element 对象,都是列表。

title_element = root_element.xpath('//title')
print(title_element[0].text)

在 lxml 中,还内置了一款 简单的类似 XPath 的路径语言,称为 ElementPath,例如查询 title,需要从 head 开始检索,否则返回 None

print(root_element[0].find("title"))

官方提供的方法如下:

  • iterfind(): 返回查找到的数据,迭代器形式返回;
  • findall(): 返回匹配到的列表;
  • find(): 返回第一个匹配到的数据;
  • findtext(): 返回匹配到的文本数据,第一个。

正则表达式 与 XPath 语法领域细解,初学阶段的你,该怎么学?

lxml 扩展知识

lxml 除了可以配合 XPath 实现数据解析外,还可以与 cssselect ,BeautifulSouphtml5lib 配合使用,这部分在后续的案例中,将逐步进行展开。

lxml 在爬虫领域,更多的是在提取数据,因此较于该库本身,掌握 XPath 等解析表达式的写法更加重要。

Python requests 模块

Python 爬虫或网络请求时,最先接触的第三方库就是 requestsrequests 库提供了中文手册 - https://docs.python-requests.org/zh_CN/latest/

requests.get() 方法

除 url 参数外,其余都为可选参数,即非必选。

  • url:请求地址;
  • params:要发送的查询字符串,可以为字典,列表,元组,字节;
  • data:body 对象中要传递的参数,可以为字段,列表,元组,字节或者文件对象
  • json:JSON 序列化对象;
  • headers:请求头,字典格式;
  • cookies:传递 cookie,字段或 CookieJar 类型;
  • files:最复杂的一个参数,一般出现在 POST 请求中,格式举例 "name":文件对象 或者 {'name':文件对象},还可以在一个请求中发送多个文件,不过一般爬虫场景不会用到;
  • auth:指定身份验证机制;
  • timeout:服务器等待响应时间,在源码中检索到可以为元组类型,这个之前没有使用过,即 (connect timeout, read timeout)
  • allow_redirects:是否允许重定向;
  • proxies:代理;
  • verify:SSL 验证;
  • stream:流式请求,主要对接流式 API;
  • cert:证书。

除了 GET 请求外,requests 还内置了其他的服务器请求方式GETOPTIONSHEADPOSTPUTPATCHDELETE
这些方法需要的参数与上述清单一致。

在 Python 爬虫的实战当中,主要以 GET 与 POST 为主,
常用的参数为:urlparamsdataheaderscookiestimeoutproxiesverify

响应对象的属性与方法

使用 requests 库请求之后,会得到一个 Response 对象,掌握该对象的技巧就是了解其属性与方法,通过 dir() 函数可以获取 Response 对象的属性和方法。

help(res)
print(dir(res))

获取到的内容如下所示,其中有我们之前案例中常见的一些内容。

['__attrs__', '__bool__', '__class__', '__delattr__', '__dict__', '__dir__', '其余内容自行查询']

如果只将 requests 库应用在爬虫采集领域,那上述属性与方法中,比较常用的有:

属性 property

  • ok:只要状态码 status_code 小于 400,都会返回 True;
  • is_redirect:重定向属性;
  • content:响应内容,字节类型;
  • text:响应内容,Unicode 类型;
  • status_code:响应状态码;
  • url:响应的最终 URL 位置;
  • encoding:当访问 r.text 时的编码;

方法

  • json():将响应结果序列化为 JSON;

会话对象

 requests 存在的高级特性,即会话对象,会话对象可以保持参数。
该对象能够在跨域请求的时候,保持住某些参数,尤其是 cookie,如果你想向同一主机发送多个请求,使用会话对象可以将底层的 TCP 连接进行重用,从而带来显著的性能提升。

会话对象使用非常简单,在发起 requests 对象之前,增加如下所示代码即可。

# 建立会话对象
s = requests.Session()
# 后续都使用会话对象进行进行,而不是直接使用 requests 对象
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get("http://httpbin.org/cookies")
print(r.text)

会话也可用来为请求方法提供缺省数据,顾名思义就是直接给会话对象增加的请求参数,

import requests
s = requests.Session()
s.auth = ('user', 'pass')
s.headers.update({'x-test': 'true'})

# both 'x-test' and 'x-test2' are sent
r = s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})

print(r.text)

方法级别的参数也不会被跨请求保持,即在 s.get() 方法中如果传递了 cookie,那不会被保持住。
通过会话对象的属性设置的参数,能被保持,而通过会话对象方法传递的参数,不能被保持。

SSL 证书验证,客户端证书,CA 证书

在爬虫采集数据的过程中,碰到 https 的网站在正常不过,requests 库使用过程中 SSL 验证是默认开启的,如果证书验证失败,即抛出 SSLError错误。

不过在实战的时候,我们可以通过设置 verify = False ,忽略对 SSL 证书的验证。
部分场景无法忽略证书,必须增加相关证书逻辑。

代理

有的网站在采集过程中,会针对 IP 进行限制,此时就需要使用代理进行跳过操作,设置 proxies 参数即可,

除了 HTTP 代理外, requests 2.10 版本之后,增加了 SOCKS 代理,如果你需要使用,需要通过 pip 安装相应库。

pip install requests[socks]

安装完毕,出现新的第三方库 PySocks,使用方式与 HTTP 代理一致。

Cookie

爬虫采集过程会大量的与 cookie 打交道,获取网站响应的 cookie,使用 response 对象的 cookies 属性即可。
如果希望向服务器传递 cookie,可以通过 cookies 参数,例如下述代码:

url = 'http://httpbin.org/cookies'
cookies = dict(cookies_are='working')
r = requests.get(url, cookies=cookies)

如果你希望对 cookie 有更加细致的操作,重点研究 requests.cookies.RequestsCookieJar 对象即可,
简单的代码使用如下所示:

jar = requests.cookies.RequestsCookieJar()
jar.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies')
jar.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere')
url = 'http://httpbin.org/cookies'
r = requests.get(url, cookies=jar)
print(r.text)

RequestsCookieJar 对象具备更加丰富的接口,适合跨域名跨路径使用,相关接口可在 https://docs.python-requests.org/zh_CN/latest/api.html#requests.cookies.RequestsCookieJar 查询。

requests 非常适合作为 Python 爬虫入门阶段第一选择,其简单的接口与代码封装,能大幅度降低网络请求代码编写难度,让你专注与目标数据的提取,更有基于高级请求的封装作为提高部分,该库完全可以贯穿你的整个爬虫工程师生涯。

提高场景

学习基本使用之后,可以使用 requests 模块实现一些简易爬虫案例,例如参考《Python 爬虫小课》,全部都是基于 requests 模块完成。

requests 模块目前在 Python 爬虫领域的出场率极高,很多简单的接口开发,也会基于它进行实现,
因此,该模块十分重要,需要牢牢掌握

Python selenium 入手篇

selenium 项目最早是为测试浏览器、网页开发的,并且广泛应用于爬虫,需要注意 selenium 不是单个软件,它其实由一系列的工具组成。

selenium 与 webdriver 是两个项目, webdriver 是对 selenium 的二次开发,selenium 存在三个大版本,关系如下所示:

selenium1.0 + webdriver = selenium2.0

selenium 安装

使用命令 pip install selenium 即可安装 selenium 库,安装完毕直接通过 import selenium 测试即可。

接下来还需要下载一个 WebDriver,它用于驱动浏览器运行。

chrome 浏览器 的 WebDriver(chromedriver.exe),可以在下述地址下载:
CNPM Binaries Mirror

firefox 浏览器的 WebDriver(geckodriver.exe),可以在下述地址下载:
https://github.com/mozilla/geckodriver/releases

其他浏览器驱动:
Edge:https://developer.microsoft.com/en-us/micrsosft-edage/tools/webdriver
Safari:WebDriver Support in Safari 10 | WebKit

一般使用 chrome 浏览器,在下载前,先查询本地 chrome 浏览器版本。
Python 自动化领域起点篇,Selenium WebDriver 学习第1篇

下载文件之后,解压到一个固定目录,记住该地址,需要在环境变量中进行配置。

G:\chromedriver_win32

测试配置是否正确:

from selenium import webdriver

driver = webdriver.Chrome()

运行代码出现谷歌浏览器,表示安装完成。

编写第一个 selenium 案例

使用 selenium 打开百度首页。

from selenium import webdriver

driver = webdriver.Chrome()

# 设置浏览器大小
driver.set_window_size(800,600)
# 可以直接最大化
driver.maximize_window()

# 打开百度
driver.get("http://www.baidu.com")

webdriver 对浏览器基本操作

基本操作包括:

  • 打开浏览器
  • 关闭浏览器
  • 前进
  • 后退
  • 刷新
from selenium import webdriver
import time

driver = webdriver.Chrome()

driver.maximize_window()  # 最大化浏览器窗口

driver.get("http://www.baidu.com")  # 打开百度

time.sleep(1)  # 暂停1秒钟
driver.get("https://www.csdn.net/")  # 打开 CSDN 首页

time.sleep(1)  # 暂停1秒钟
driver.back()  # 回退

time.sleep(1)  # 暂停1秒钟
driver.forward()  # 前进

time.sleep(1)  # 暂停1秒钟
driver.refresh()  # 页面刷新

time.sleep(1)  # 暂停1秒钟
driver.quit()  # 浏览器关闭

网页元素定位

元素定位需要 HTML 基础支持,这部分内容直接百度学习即可,selenium 提供了 8 种网页元素定位方式,分别如下:

  1. 根据 ID 定位,对应的方法是 find_element_by_id() 和 find_elements_by_id()
  2. 根据 class 定位,对应的方法是 find_element_by_class_name() 和 find_elements_by_class_name()
  3. 根据标签名定位,对应的方法是 find_element_by_tag_name() 和 find_elements_by_tag_name()
  4. 根据 CSS 选择器定位,对应的方法是 find_element_by_css_selector() 和 find_elements_by_css_selector()
  5. 根据 name 定位,对应的方法是 find_element_by_name() 和 find_elements_by_name()
  6. 使用 XPath 定位,对应的方法是 find_element_by_xpath() 和 find_elements_by_xpath()
  7. 根据链接文本定位,对应的方法是 find_element_by_link_text() 和 find_elements_by_link_text()
  8. 根据部分链接文本定位,对应的方法是 find_element_by_partial_link_text() 和 find_elements_by_partial_link_text()

其中返回 element 表示单数(第一个),返回 elements 表示复数,得到全部。

接下来用 简书 jianshu.com 首页,完成定位测试。

通过 ID 与 name 进行定位

from selenium import webdriver

driver = webdriver.Chrome()

driver.maximize_window()  # 最大化浏览器窗口

driver.get("http://www.jianshu.com")  # 打开简书

driver.find_element_by_id("q").send_keys("梦想橡皮擦")  # 通过ID检索搜索框,并输入文本
driver.find_element_by_class_name("search-btn").click()  # 通过 class name 搜索按钮,并点击

这里调用方法出现了一个问题,解决方式如下: 

关于新版本selenium定位元素报错:‘WebDriver‘ object has no attribute ‘find_element_by_id‘等问题

代码中的 send_keys() 表示想目标元素输入数据,click() 表示点击操作

查看元素各种属性依赖浏览器的开发者工具,这些都属于前端知识,大家可以针对性的补充。

通过 XPath 表达式进行定位

XPath 定位重点要学习的是 XPath 语句的写法,可以参考:正则表达式 与 XPath 语法领域细解,初学阶段的你,该怎么学?_梦想橡皮擦的博客-CSDN博客_xpath和正则表达式 进行学习。

通过 class(类)名进行定位
注意该定位方式不支持复合类名,例如 <ul class="nav navbar-nav"></i>,无法使用 driver.find_element_by_class_name("nav navbar-nav") 进行获取,仅支持单独的 class 名称。

其余获取元素的方式基本雷同,一般情况下使用 ID 和 class(类)名获取元素场景比较多。

selenium 入手篇扩展知识

安装 PhanomJS

仅作为扩展知识,最新版本的 selenium 已经不支持 PhanomJS

PhanomJS 是一款隐形浏览器(无界面 / 无头浏览器),主要用于自动化测试,网络爬虫,网络监控等领域。

下载与安装非常简单,打开国内镜像网站下载即可,一般不要下载 beta 版本。

https://npm.taobao.org/mirrors/phantomjs

在这里插入图片描述
解压文件,获取 bin 目录完整路径,填写到环境变量中。
配置完毕,在控制台输入 phantomjs -v 查看程序对应版本。
Python 自动化领域起点篇,Selenium WebDriver 学习第1篇
由于谷歌和火狐浏览器都推出了无头浏览器,所以 selenium 弃用了 PhantomJS,使用 Chrome 无头浏览器的方式为:

使用无头浏览器 

from selenium import webdriver

opt = webdriver.ChromeOptions()  # 创建 chrome 参数对象

opt.headless = True  # 设置无头浏览器

driver = webdriver.Chrome(options=opt)  # 创建 chrome 无界面对象

driver.get("http://www.jianshu.com")  # 打开简书

title = driver.title
print("网页标题是:", title)

driver.save_screenshot("./jianshu.png")#保存截图

有的博客在设置无头浏览器时,会使用如下函数:opt.set_headless(),不过在最新版本中也已经被废弃,使用 opt.headless 即可。

还可以编写如下代码:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

opt = Options()  # 创建 chrome 参数对象
opt.add_argument('-headless')  # 无头参数

driver = webdriver.Chrome(options=opt)  # 创建 chrome 无界面对象

driver.get("http://www.jianshu.com")  # 打开简书

title = driver.title
print("网页标题是:", title)

driver.save_screenshot("./jianshu.png")

selenium 退出有两种方式:

  • driver.close():不会清除临时文件夹中的 WebDriver 临时文件;
  • driver.quit():删除临时文件夹。

表象的理解 close 与 quit 的区别是,close 关闭浏览器当前标签,quit 关闭浏览器。

猜你喜欢

转载自blog.csdn.net/m0_51933492/article/details/127804391
今日推荐