爬虫知识
requests模块 安装:pip install requests
requests模块发送get请求
1 2 3 4 5 6 7 8 9 10 11 12 import requests url = 'https://www.baidu.com' response = requests.get(url)print (response.text)print (response.content.decode())
response response.text 和response.content区别 response.text
类型:str
解码类型: requests模块自动根据HTTP 头部对响应的编码作出有根据的推测,推测的文本编码
response.content
属性
response = requests.get(url)
中response是发送请求获取的响应对象;response响应对象中除了text、content获取响应内容以外还有其它常用的属性或方法:
response.url
响应的url;有时候响应的url和请求的url并不一致
response.status_code
响应状态码
response.request.headers
响应对应的请求头
response.headers
响应头
response.request._cookies
响应对应请求的cookie;返回cookieJar类型
response.cookies
响应的cookie(经过了set-cookie动作;返回cookieJar类型
response.json()
自动将json字符串类型的响应内容转换为python对象(dict or list
1 2 3 4 response.content.decode() response.content.decode("GBK" )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import requests url = 'https://www.baidu.com' response = requests.get(url)print (response.url) print (response.status_code) print (response.request.headers) print (response.headers) print (response.request._cookies) print (response.cookies)
携带参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import requests url = 'https://www.baidu.com' headers = { "User-Agent" : "请求头" , 'Cookie' : 'xxx这里是复制过来的cookie字符串' } kw = {'wd' : 'python' } response = requests.get(url, headers=headers, params=kw)
cookies使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import requests url = 'https://github.com/USER_NAME' headers = { 'User-Agent' : '请求头' } cookies_str = '从浏览器中copy过来的cookies字符串' cookies_dict = {cookie.split('=' )[0 ]:cookie.split('=' )[-1 ] for cookie in cookies_str.split('; ' )} resp = requests.get(url, headers=headers, cookies=cookies_dict)print (resp.text)
cookieJar对象转换为cookies字典的方法
1 2 cookies_dict = requests.utils.dict_from_cookiejar(response.cookies)
timeout使用 1 2 3 4 import requests url = 'https://twitter.com' response = requests.get(url, timeout=3 )
代理 1 2 3 4 5 proxies = { "http" : "http://12.34.56.79:9527" , "https" : "https://12.34.56.79:9527" , } response = requests.get(url, proxies=proxies)
忽略CA证书 1 2 3 import requests url = "https://sam.huat.edu.cn:8443/selfservice/" response = requests.get(url,verify=False )
jsonpath模块 安装:pip install jsonpath
1 2 from jsonpath import jsonpath ret = jsonpath(a, 'jsonpath语法规则字符串' )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 book_dict = { "store" : { "book" : [ { "category" : "reference" , "author" : "Nigel Rees" , "title" : "Sayings of the Century" , "price" : 8.95 }, { "category" : "fiction" , "author" : "Evelyn Waugh" , "title" : "Sword of Honour" , "price" : 12.99 } ], "bicycle" : { "color" : "red" , "price" : 19.95 } } }from jsonpath import jsonpathprint (jsonpath(book_dict, '$..author' ))
xpath
xpath节点
xpath基础语法
XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。
这些路径表达式和我们在常规的电脑文件系统中看到的表达式 非常相似。
使用chrome插件选择标签时候,选中时,选中的标签会添加属性class=”xh-highlight”
表达式
描述
nodename
选中该元素。
/
从根节点选取、或者是元素和元素间的过渡。
//
从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
.
选取当前节点。
..
选取当前节点的父节点。
@
选取属性。
text()
选取文本。
选择所有的h2下的文本://h2/text()
获取所有的a标签的href://a/@href
获取html下的head下的title的文本:/html/head/title/text()
获取html下的head下的link标签的href:/html/head/link/@href
节点修饰语法 下标
在xpath中,第一个元素的位置是1
最后一个元素的位置是last()
倒数第二个是last()-1
路径表达式
结果
//title[@lang=”eng”]
选择lang属性值为eng的所有title元素
/bookstore/book[1]
选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()]
选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1]
选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()>1]
选择bookstore下面的book元素,从第二个开始选择
//book/title[text()=’Harry Potter’]
选择所有book下的title元素,仅仅选择文本为Harry Potter的title元素
/bookstore/book[price>35.00]/title
选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。
通配符
描述
*
匹配任何元素节点。
node()
匹配任何类型的节点。
lxml模块 安装:pip/pip3 install lxml
lxml模块的使用
导入lxml 的 etree 库
from lxml import etree
利用etree.HTML,将html字符串(bytes类型或str类型)转化为Element对象,Element对象具有xpath的方法,返回结果的列表
1 2 html = etree.HTML(text) ret_list = html.xpath("xpath语法规则字符串" )
xpath方法返回列表的三种情况
返回空列表:根据xpath语法规则字符串,没有定位到任何元素
返回由字符串构成的列表:xpath字符串规则匹配的一定是文本内容或某属性的值
返回由Element对象构成的列表:xpath规则字符串匹配的是标签,列表中的Element对象可以继续进行xpath
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 from lxml import etree text = ''' <div> <ul> <li class="item-1"> </li> <li class="item-1"> </li> <li class="item-inactive"> </li> <li class="item-1"> </li> <li class="item-0"> a href="link5.html">fifth item</a> </ul> </div> ''' html = etree.HTML(text) href_list = html.xpath("//li[@class='item-1']/a/@href" ) title_list = html.xpath("//li[@class='item-1']/a/text()" )for href in href_list: item = {} item["href" ] = href item["title" ] = title_list[href_list.index(href)] print (item)
其他
lxml.etree.HTML(html_str)可以自动补全标签
lxml.etree.tostring
函数可以将转换为Element对象再转换回html字符串
爬虫如果使用lxml来提取数据,应该以lxml.etree.tostring
的返回结果作为提取数据的依据
selenium使用 Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium 可以直接调用浏览器,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器),可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏等
selenium安装 python安装:pip3 install selenium
chrome安装
https://npm.taobao.org/mirrors/chromedriver 下载对应版本的
解压压缩包后获取python代码可以调用的谷歌浏览器的webdriver可执行文件
windows环境下需要将 chromedriver.exe 所在的目录设置为path环境变量中的路径
linux/mac环境下,将 chromedriver 所在的目录设置到系统的PATH环境值中
selenium使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import timefrom selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.baidu.com/" ) driver.find_element_by_id('kw' ).send_keys('python' ) driver.find_element_by_id('su' ).click() time.sleep(6 ) driver.quit()
driver对象的常用属性和方法
在使用selenium过程中,实例化driver对象后,driver对象有一些常用的属性和方法
driver.page_source
当前标签页浏览器渲染之后的网页源代码
driver.current_url
当前标签页的url
driver.close()
关闭当前标签页,如果只有一个标签页则关闭整个浏览器
driver.quit()
关闭浏览器
driver.forward()
页面前进
driver.back()
页面后退
driver.screen_shot(img_name)
页面截图
在selenium中可以通过多种方式来定位标签,返回标签元素对象
1 2 3 4 5 6 7 8 find_element_by_id (返回一个元素) find_element(s)_by_class_name (根据类名获取元素列表) find_element(s)_by_name (根据标签的name属性值返回包含标签对象元素的列表) find_element(s)_by_xpath (返回一个包含元素的列表) find_element(s)_by_link_text (根据连接文本获取元素列表) find_element(s)_by_partial_link_text (根据链接包含的文本获取元素列表) find_element(s)_by_tag_name (根据标签名获取元素列表) find_element(s)_by_css_selector (根据css选择器来获取元素列表)
find_element和find_elements的区别:
多了个s就返回列表,没有s就返回匹配到的第一个标签对象
find_element匹配不到就抛出异常,find_elements匹配不到就返回空列表
by_link_text和by_partial_link_tex的区别:全部文本和包含某个文本
以上函数的使用方法
driver.find_element_by_id('id_str')
selenium标签页的切换 1 2 3 4 5 current_windows = driver.window_handles driver.switch_to.window(current_windows[0 ])
参考代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import timefrom selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.baidu.com/" ) time.sleep(1 ) driver.find_element_by_id('kw' ).send_keys('python' ) time.sleep(1 ) driver.find_element_by_id('su' ).click() time.sleep(1 ) js = 'window.open("https://www.sogou.com");' driver.execute_script(js) time.sleep(1 ) windows = driver.window_handles time.sleep(2 ) driver.switch_to.window(windows[0 ]) time.sleep(2 ) driver.switch_to.window(windows[1 ]) time.sleep(6 ) driver.quit()
switch_to切换frame标签 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import timefrom selenium import webdriver driver = webdriver.Chrome() url = 'https://mail.qq.com/cgi-bin/loginpage' driver.get(url) time.sleep(2 ) login_frame = driver.find_element_by_id('login_frame' ) driver.switch_to.frame(login_frame) driver.find_element_by_xpath('//*[@id="u"]' ).send_keys('1596930226@qq.com' ) time.sleep(2 ) driver.find_element_by_xpath('//*[@id="p"]' ).send_keys('hahamimashicuode' ) time.sleep(2 ) driver.find_element_by_xpath('//*[@id="login_button"]' ).click() time.sleep(2 )"""操作frame外边的元素需要切换出去""" windows = driver.window_handles driver.switch_to.window(windows[0 ]) content = driver.find_element_by_class_name('login_pictures_title' ).textprint (content) driver.quit()
切换到定位的frame标签嵌套的页面中:driver.switch_to.frame(通过find_element_by函数定位的frame、iframe标签对象)
利用切换标签页的方式切出frame标签
1 2 windows = driver.window_handles driver.switch_to.window(windows[0 ])
selenium对cookie的处理 获取cookie
driver.get_cookies()
返回列表,其中包含的是完整的cookie信息!不光有name、value,还有domain等cookie其他维度的信息。所以如果想要把获取的cookie信息和requests模块配合使用的话,需要转换为name、value作为键值对的cookie字典
1 2 3 4 print (driver.get_cookies()) cookies_dict = {cookie[‘name’]: cookie[‘value’] for cookie in driver.get_cookies()}
删除cookie 1 2 3 4 5 driver.delete_cookie("CookieName" ) driver.delete_all_cookies()
selenium控制浏览器执行js代码 执行js的方法:driver.execute_script(js)
1 2 3 4 5 6 7 8 9 10 11 12 import timefrom selenium import webdriver driver = webdriver.Chrome() driver.get("http://www.baidu.com/" ) time.sleep(1 ) js = 'window.scrollTo(0,document.body.scrollHeight)' driver.execute_script(js) time.sleep(5 ) driver.quit()
页面等待分类
强制等待
隐式等待
显式等待
强制等待 其实就是time.sleep()
缺点时不智能,设置的时间太短,元素还没有加载出来;设置的时间太长,则会浪费时间
隐式等待 隐式等待针对的是元素定位,隐式等待设置了一个时间,在一段时间内判断元素是否定位成功,如果完成了,就进行下一步
在设置的时间内没有定位成功,则会报超时加载
1 2 3 4 5 6 7 8 9 from selenium import webdriver driver = webdriver.Chrome() driver.implicitly_wait(10 ) driver.get('https://www.baidu.com' ) driver.find_element_by_xpath()
显式等待 每经过多少秒就查看一次等待条件是否达成,如果达成就停止等待,继续执行后续代码
如果没有达成就继续等待直到超过规定的时间后,报超时异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get('https://www.baidu.com' ) WebDriverWait(driver, 20 , 0.5 ).until( EC.presence_of_element_located((By.LINK_TEXT, '好123' ))) print (driver.find_element_by_link_text('好123' ).get_attribute('href' )) driver.quit()
selenium开启无界面模式 绝大多数服务器是没有界面的,selenium控制谷歌浏览器也是存在无界面模式的
实例化配置对象:options = webdriver.ChromeOptions()
配置对象添加开启无界面模式的命令:options.add_argument("--headless")
配置对象添加禁用gpu的命令:options.add_argument("--disable-gpu")
实例化带有配置对象的driver对象:driver = webdriver.Chrome(chrome_options=options)
注意:macos中chrome浏览器59+版本,Linux中57+版本才能使用无界面模式
1 2 3 4 5 6 7 8 9 10 11 12 from selenium import webdriver options = webdriver.ChromeOptions() options.add_argument("--headless" ) options.add_argument("--disable-gpu" ) driver = webdriver.Chrome(chrome_options=options) driver.get('http://www.baidu.com' )print (driver.title) driver.quit()
phantomjs无界面浏览器 PhantomJS 是一个基于Webkit的“无界面”(headless)浏览器,它会把网站加载到内存并执行页面上的 JavaScript。下载地址:http://phantomjs.org/download.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from selenium import webdriver driver = webdriver.PhantomJS(executable_path='/home/worker/Desktop/driver/phantomjs' ) driver.get("http://www.baidu.com/" ) driver.save_screenshot("1.png" ) driver.quit()
selenium使用代理ip 实例化配置对象:options = webdriver.ChromeOptions()
配置对象添加使用代理ip的命令:options.add_argument('--proxy-server=http://202.20.16.82:9527')
实例化带有配置对象的driver对象:driver = webdriver.Chrome('./chromedriver', chrome_options=options)
1 2 3 4 5 6 7 8 9 10 from selenium import webdriver options = webdriver.ChromeOptions() options.add_argument('--proxy-server=http://202.20.16.82:9527' ) driver = webdriver.Chrome(chrome_options=options) driver.get('http://www.baidu.com' )print (driver.title) driver.quit()
selenium替换user-agent 实例化配置对象:options = webdriver.ChromeOptions()
配置对象添加替换UA的命令:options.add_argument('--user-agent=Mozilla/5.0 HAHA')
实例化带有配置对象的driver对象:driver = webdriver.Chrome('./chromedriver', chrome_options=options)
1 2 3 4 5 6 7 8 9 10 from selenium import webdriver options = webdriver.ChromeOptions() options.add_argument('--user-agent=Mozilla/5.0 HAHA' ) driver = webdriver.Chrome('./chromedriver' , chrome_options=options) driver.get('http://www.baidu.com' )print (driver.title) driver.quit()
相关文章
Python基础
Mongodb和Python交互
Python反爬解决方案
Mongodb和Python交互
Python反爬解决方案
Scrapy爬虫
Scrapy爬虫
Python打包可执行文件