bs4详解,css选择器,selenium基本使用,无界面浏览器,selenium其它用法

bs4详解,css选择器,selenium基本使用,无界面浏览器,selenium其它用法

bs4详解

'''
bs4:全称 beautifulsoup4,从HTML或者HTML文件中提取数据的Python库,用来解析爬取回来的xml
安装:pip install beautifulsoup4
	 pip install lxml    安装解析库
soup = BeautifulSoup('要解析的内容str类型','html.parse/lxml') 
'''

下表列出了主要的解析器,以及它们的优缺点,官网推荐使用lxml作为解析器,因为效率更高

image

bs4的遍历文档树

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><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>
"""

# 1 美化,不是标准xml,完成美化
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc,'lxml')
res =soup.prettify()   # 美化
print(res)

# 2 遍历文档树---》通过 . 来遍历
print(soup.html.body.p)  # 一层一层找
print(soup.p)  # 跨层  只找第一个

#3、获取标签的名称
print(soup.a.name)

#4、获取标签的属性  ---》属性字典
print(soup.a.attrs['href'])
print(soup.a.attrs.get('class'))   # class 会有多个 ['sister']
print(soup.a.attrs.get('name'))

#5、获取标签的内容
# text  获得该标签内部子子孙孙所有标签的文本内容
print(soup.p.text)
# string p下的文本只有一个时,取到,否则为None
print(soup.p.string)
# strings
print(list(soup.p.strings)) # generator

# 6、嵌套选择
print(soup.html.body)


了解的知识点:

#7、子节点、子孙节点
print(soup.body.contents) #p下所有子节点,只取一层
print(list(soup.p.children)) #list_iterator得到一个迭代器,包含p下所有子节点  只取一层
print(list(soup.body.descendants) ) # generator  子子孙孙

#8、父节点、祖先节点
print(soup.a.parent) #获取a标签的父节点  直接父亲
print(list(soup.a.parents) )#找到a标签所有的祖先节点,父亲的父亲,父亲的父亲的父亲...

#8、兄弟节点
print(soup.a.next_sibling) #下一个兄弟
print(soup.a.previous_sibling) #上一个兄弟
print(list(soup.a.next_siblings)) #下面的兄弟们=>生成器对象
print(list(soup.a.previous_siblings)) #上面的兄弟们=>生成器对象

搜索文档树

1、五种过滤器
#1、五种过滤器: 字符串、正则表达式、列表、True、方法
#1.1、字符串:即标签名
print(soup.find_all('b'))

#1.2、正则表达式
import re
print(soup.find_all(re.compile('^b'))) #找出b开头的标签,结果有body和b标签

#1.3、列表:如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回.下面代码找到文档中所有<a>标签和<b>标签:
print(soup.find_all(['a','b']))

#1.4、True:可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点
print(soup.find_all(True))
for tag in soup.find_all(True):
    print(tag.name)
    
#1.5、方法:如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数 ,如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False
def has_class_but_no_id(tag):
    return tag.has_attr('class') and not tag.has_attr('id')

print(soup.find_all(has_class_but_no_id))
2.find的其他参数
limit:限制调试,find_all用        find的本质是find_all + limit=1
limit:如果文档树很大那么搜索会很慢.如果我们不需要全部结果,可以使用 limit 参数限制返回结果的数量.效果与SQL中的limit关键字类似,当搜索到的结果数量达到 limit 的限制时,就停止搜索返回结果
    
recursive:调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False .
# limit 参数
res = soup.find_all(href = True,limit=2)
print(res)

# recursive  查找的时候,是只找第一层还是子子孙孙都找
res=soup.find_all(name='b',recursive=False)
res=soup.find_all(name='b')
print(res)

css选择器

#该模块提供了select方法来支持css,详见官网:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#id37
# select内写css选择器
print(soup.select('.sister'))

print(soup.select('#link1'))
print(soup.select('#link1 span'))

import requests
res = requests.get('https://www.w3school.com.cn/css/css_selector_attribute.asp')
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc,'lxml')
print(soup.select('#intro > p:nth-child(1) > strong')[0].text)

selenium基本使用

# selenium的介绍
selenium最初是一个自动化测试工具,而爬虫中使用它是为了解决requests无法直接执行JS代码的问题
selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转,输入,点击,下拉等,来拿到网页渲染之后的结果,可支持多种浏览器
1 下载selenium
2 操作浏览器:分不同浏览器,需要下载不同浏览器的驱动
   -用谷歌---》谷歌浏览器驱动:https://registry.npmmirror.com/binary.html?path=chromedriver/
   -跟谷歌浏览器版本要对应  :
3 下载完的驱动,放在项目路径下
4 写代码,控制谷歌浏览器

from selenium import webdriver
import time
bro = webdriver.Chrome(executable_path='chromedriver.exe')   # 打开谷歌浏览器
bro.get('https://www.baidu.com/s?wd=%E9%9E%A0%E5%A9%A7%E7%A5%8E')
print(bro.page_source)
with open('1.html','w',encoding='utf-8') as f:
    f.write(bro.page_source)
time.sleep(9)
bro.close()

image

无界面浏览器


from selenium import webdriver
import time
from selenium.webdriver.chrome.options import Options
# 隐藏浏览器的图形化界面,但是数据还拿到
chrome_options = Options()
chrome_options.add_argument('window-size=1920x3000') #指定浏览器分辨率
chrome_options.add_argument('--hide-scrollbars') #隐藏滚动条, 应对一些特殊页面
chrome_options.add_argument('blink-settings=imagesEnabled=false') #不加载图片, 提升速度
chrome_options.add_argument('--headless') #浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败


bro = webdriver.Chrome(executable_path='chromedriver.exe',chrome_options=chrome_options)   # 打开谷歌浏览器
# bro = webdriver.Chrome(executable_path='chromedriver.exe')   # 打开谷歌浏览器
# 隐藏浏览器的图形化界面,但是数据还能拿到
bro.get('https://www.bilibili.com/')
print(bro.page_source)
time.sleep(9)
bro.close()

模拟登录百度


from selenium import webdriver
import time
from selenium.webdriver.common.by import By


bro = webdriver.Chrome(executable_path='chromedriver.exe')   # 打开谷歌浏览器
# 隐藏浏览器的图形化界面,但是数据还能拿到
bro.get('https://www.baidu.com/')
# 加入等待:找标签
bro.implicitly_wait(10)
# 从页面中找到登录,然后点击它
btn = bro.find_element(by=By.LINK_TEXT,value='登录')
btn.click()

#TANGRAM__PSP_11__changePwdCodeItem
btn_2 = bro.find_element(by=By.ID,value='TANGRAM__PSP_11__changePwdCodeItem')
btn_2.click()
time.sleep(3)

# 找到按账号登录的点击按钮,有id,优先用id,因为唯一
#TANGRAM__PSP_11__changeSmsCodeItem
btn_2 = bro.find_element(by=By.ID,value='TANGRAM__PSP_11__changeSmsCodeItem')
btn_2.click()
time.sleep(3)


#TANGRAM__PSP_11__changePwdCodeItem
btn_2 = bro.find_element(by=By.ID,value='TANGRAM__PSP_11__changePwdCodeItem')
btn_2.click()
time.sleep(3)

#TANGRAM__PSP_11__userName
name = bro.find_element(by=By.ID,value='TANGRAM__PSP_11__userName')
#TANGRAM__PSP_11__password
password = bro.find_element(by=By.ID,value='TANGRAM__PSP_11__password')
name.send_keys('306334678@qq.com')
password.send_keys('12345555')
time.sleep(3)

#TANGRAM__PSP_11__submit
submit=bro.find_element(by=By.ID,value='TANGRAM__PSP_11__submit')
submit.click()
time.sleep(3)
bro.close()  # 关闭浏览器

image

selenium其它用法

查找标签

# 两个方法
bro.find_element   找一个
bro.find_elements  找所有

# 可以按id,标签名,name属性名,类名,a标签的文字,a标签的文字模糊匹配,css选择器,xpath【后面聊】
input_1=bro.find_element(by=By.ID,value='wd')  # 按id找
input_1 = bro.find_element(by=By.NAME, value='wd')  # name属性名
input_1=bro.find_element(by=By.TAG_NAME,value='input') # 可以按标签名字找

input_1=bro.find_element(by=By.CLASS_NAME,value='s_ipt') # 可以按类名
input_1=bro.find_element(by=By.LINK_TEXT,value='登录') # 可以按a标签内容找
input_1=bro.find_element(by=By.PARTIAL_LINK_TEXT,value='录') # 可以按a标签内容找
input_1 = bro.find_element(by=By.CSS_SELECTOR, value='#su')  # 可以按css选择器

获取位置属性大小,文本

print(tag.get_attribute('src'))  # 用的最多
tag.text  # 文本内容
#获取标签ID,位置,名称,大小(了解)
print(tag.id)
print(tag.location)
print(tag.tag_name)
print(tag.size)

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import base64
bro = webdriver.Chrome(executable_path='./chromedriver.exe')
bro.get('https://kyfw.12306.cn/otn/resources/login.html')
# bro.get('https://www.jd.com/')

a = bro.find_element(by=By.LINK_TEXT, value='扫码登录')
# a = bro.find_element(by=By.CSS_SELECTOR, value='.login-hd-account>a')
a.click()
# code = bro.find_element(by=By.ID, value='J-qrImg')
code = bro.find_element(by=By.CSS_SELECTOR, value='#J-qrImg')
# code = bro.find_element(by=By.CSS_SELECTOR, value='.logo_scene_img')

# # 方案一:通过位置,和大小,截图截出来
print(code.id)
print(code.location)
print(code.tag_name)
print(code.size)

# # 方案二:通过src属性获取到图片
print(code.location)
print(code.size)
print(code.id)  # 不是标签的id号
print(code.tag_name)  # 是标签的名字
s = code.get_attribute('src')
print(s)
with open('code.png','wb') as f:
    res=base64.b64decode(s.split(',')[-1])
    f.write(res)

time.sleep(3)

bro.close()



等待元素被加载

# 代码执行很快,有的标签没来的及加载,直接查找就会报错,设置等待
# 隐士等待:所有标签,只要去找,找不到就遵循 等10s的规则
	bro.implicitly_wait(10)
# 显示等待:需要给每个标签绑定一个等待,麻烦

元素操作

# 点击
tag.click()
# 输入内容
tag.send_keys()
# 清空内容
tag.clear()
# 浏览器对象 最大化
bro.maximize_window() 
#浏览器对象  截全屏
bro.save_screenshot('main.png')

执行js代码

bro.execute_script('alert("美女")')  # 引号内部的相当于 用script标签包裹了

# 可以干的事
	-获取当前访问的地址  window.location
    -打开新的标签
    -滑动屏幕--》bro.execute_script('scrollTo(0,document.documentElement.scrollHeight)')
    -获取cookie,获取定义的全局变量

切换选项卡

import time
from selenium import webdriver

bro = webdriver.Chrome(executable_path='./chromedriver.exe')
bro.get('https://www.jd.com/')
# s使用js打开新的选项卡
bro.execute_script('window.open()')
# 切换到这个选项卡上,刚刚打开的是第一个
bro.switch_to.window(bro.window_handles[1])
bro.get('https://weibo.com/')
time.sleep(2)
# 睡俩秒以后跳转到在调到开始页面
bro.switch_to.window(bro.window_handles[0])
# 睡3秒以后关闭页面
time.sleep(3)
bro.close()
bro.quit()

浏览器前进后退

import time
from selenium import webdriver

browser=webdriver.Chrome(executable_path='chromedriver.exe')
browser.get('https://www.baidu.com')
browser.get('https://www.taobao.com')
browser.get('http://www.sina.com.cn/')

browser.back()
time.sleep(2)
browser.forward()
browser.close()

异常处理

import time
from selenium import webdriver

browser=webdriver.Chrome(executable_path='chromedriver.exe')
try:
except Exception as e:
    print(e)
    
finally:
    browser.close()
posted @ 2023-03-17 20:01  小王应该在学习!  阅读(325)  评论(0编辑  收藏  举报