爬虫
import requsets header = { 'User-Agent': '', } response = requests.get('https://haokan.baidu.com/', headers=header) # response.encoding = 'utf-8' print(response.text)
from selenium.webdriver import Chrome from selenium.webdriver.common.keys import Keys import time # 1.创建浏览器 b = Chrome() # 2.打开网页 b.get('https://www.51job.com/') # 3.获取标签 search_input = b.find_element_by_id('kwdselectid') # search_input = b.find_element_by_css_selector('#kwdselectid') print(search_input) # 4.输入框中输入内容 search_input.send_keys('会计') # 输入框中按回车 search_input.send_keys(Keys.ENTER) # 5.获取网页数据 print(b.page_source) # 6.获取下一页对应的标签 next = b.find_element_by_css_selector('.next') # 7.点击按钮 next.click() print('-----------------------------------') time.sleep(2) print(b.page_source)
图片下载
import requests def download_image(img_url: str): # 请求网络图片数据 response = requests.get(img_url) # 获取数据保存到本地文件 data = response.content # 保存数据到本地文件 f = open(f'files/{img_url.split("/")[-1]}', 'wb') f.write(data) if __name__ == '__main__': download_image(url)
解析
bs4
from bs4 import BeautifulSoup soup = BeautifulSoup(html, 'lxml')
BeautifulSoup的用法
beautifulSoup是一个灵活又方便的网页解析库,处理高效,支持多种解析器。利用它不用编写正则表达式即可方便地实现网页信息的提取。
安装
通过指令:
pip install beautifulsoup4
或者在pycharm第三方库安装页面中搜索安装beautifulsoup4即可。使用
解析库
解析器 使用方法 优势 劣势 Python标准库 BeautifulSoup(markup, ‘html.parser’) Python的内置标准库、执行速度适中、文档容错能力强 低版本中文容错能力差 lxml HTML解析器 BeautifulSoup(markup, ‘lxml’) 速度快、文档容错能力强 需要安装C语言库 lxml XML解析器 BeautifulSoup(markup, ‘xml’) 速度快、唯一支持xml的解析器 需要安装C语言库 Html5lib BeautifulSoup(markup, ‘html5lib’) 最好的容错性、以浏览器的方式解析文档、生成HTML5格式的文档 速度慢,不依赖外部扩展 基本使用
- 创建解析器对象: BeautifulSoup(html文本内容, 解析器)
from bs4 import BeautifulSoup html = """ <html><head><title>The Dormouse's story</title></head> <body> <p class="title" name="dromouse"><b>The Dormouse's story</b></p> <p class="story">Once upon a time there were three little sisters; and their names were <a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>, <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> <p class="story">...</p> """ soup = BeautifulSoup(html, 'lxml') print(soup.prettify()) print(soup.title.string)
标签选择器
- 解析器对象.标签名
# 获取title标签 print(soup.title) print(type(soup.title)) # 获取 head 标签 print(soup.head) # 获取 p 标签 print(soup.p)
获取名称
- 标签对象.name
print(soup.title.name) # 'title'
获取属性
- 标签对象.attrs[属性名]
print(soup.a.attrs['href']) # ’http://example.com/elsie‘
获取内容
- 标签对象.string
- 标签对象.get_text()
- 内容:标签对象.contents
print(soup.p.string) # The Dormouse's story
嵌套选择
- 解析器对象.标签1.标签2
print(soup.head.title.string)
子节点和子孙节点
- 子节点:标签对象.children
- 子孙节点:标签对象.descendants
print(soup.p.contents) for x in soup.div.children: print('x:', x) for x in soup.div.descendants: print('x:', x)
父节点和祖先节点
- 父节点:标签对象.parent
- 祖先节点:标签对象.parents
print(soup.span.parent) for x in soup.span.parents: print('x:', x)
兄弟节点
- 标签对象.next_siblings
- 标签对象.previous_siblings
print(list(enumerate(soup.a.next_siblings))) print(list(enumerate(soup.a.previous_siblings)))
标准选择器
- 根据标签名查找标签:解析器对象/标签对象.find_all(标签名)
- 根据指定属性值查找标签: 解析器对象/标签对象.find_all(attrs={属性名: 属性值})
- 根据标签内容查找:解析器对象/标签对象.find_all(text=内容)
find_all表示查找所有,把它改成find表示查找单个
print(soup.find_all('ul')) print(type(soup.find_all('ul')[0])) for ul in soup.find_all('ul'): print(ul.find_all('li')) print(soup.find_all(attrs={'id': 'list-1'})) print(soup.find_all(attrs={'name': 'elements'})) print(soup.find_all(id='list-1')) print(soup.find_all(class_='element')) print(soup.find_all(text='Foo'))
- find_parents()返回所有祖先节点,find_parent()返回直接父节点。
- find_next_siblings()返回后面所有兄弟节点,find_next_sibling()返回后面第一个兄弟节点。
- find_previous_siblings()返回前面所有兄弟节点,find_previous_sibling()返回前面第一个兄弟节点。
- find_all_next()返回节点后所有符合条件的节点, find_next()返回第一个符合条件的节点
- find_all_previous()返回节点后所有符合条件的节点, find_previous()返回第一个符合条件的节点
CSS选择器
- 标签对象.select(css选择器)
print(soup.select('.panel .panel-heading')) print(soup.select('ul li')) print(soup.select('#list-2 .element')) print(type(soup.select('ul')[0]))
select_one只获取选择器选中的一个标签
总结
- 推荐使用lxml解析库,必要时使用html.parser
- 标签选择筛选功能弱但是速度快
- 建议使用find()、find_all() 查询匹配单个结果或者多个结果
- 如果对CSS选择器熟悉建议使用select()
- 记住常用的获取属性和文本值的方法
xpath
from lxml import etree html = etree.HTML(网页源码)
XPath的使用
XPath常用规则
选取节点
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。
表达式 描述 节点名称 选取此节点的所有子节点。 / 从根节点选取。(绝对路径) // 提取任意子节点(从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。) . 选取当前节点。 … 选取当前节点的父节点。 @ 选取属性。 实例:
路径表达式 结果 bookstore 选取 bookstore 元素的所有子节点。 /bookstore 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。 //book 选取所有 book 子元素,而不管它们在文档中的位置。 bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 //@lang 选取名为 lang 的所有属性 谓语
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
路径表达式 结果 /bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。 /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。 选取未知节点
XPath 通配符可用来选取未知的 XML 元素。
通配符 描述 * 匹配任何元素节点 @* 匹配任何属性节点。 node() 匹配任何类型的节点 实例:
路径表达式 结果 /bookstore/* 选取 bookstore 元素的所有子元素。 //* 选取文档中的所有元素。 //title[@*] 选取所有带有属性的 title 元素。 选取若干路径
通过在路径表达式中使用“|”运算符,您可以选取若干个路径。
路径表达式 结果 //book/title|//book/price 选取 book 元素的所有 title 和 price 元素。 //title|//price 选取文档中的所有 title 和 price 元素。 /bookstore/book/title|//pric 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。