Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器。lxml 解析器更加强大,速度更快,推荐安装。
抓取网页
爬取之前, 还需要查看判断爬取到的网页是动态加载还是静态加载, 如果是动态加载还需进一步处理
浏览器(Chrome、Firefox)调试器判断法;
用浏览器(以Chrome为例)打开一个网页,等待网页完全打开之后,开启浏览器控制台:”开发者工具”-“错误控制台”,快捷键:shift+ctrl+J ,然后在控制台里面输入:alert(document.lastModified); ,按回车键后查看最后修改时间并记录。
多次刷新网页,用同样的方法,比较弹窗的时间,如果都是一样的,那就是静态网页,否则就是伪静态(动态网页)。
需要注意的是, 部分网页虽然用此方法判断是动态, 但是其页面依旧可以使用request获取。
如果是静态网页使用request库
from bs4 import BeautifulSoup
# 首先使用request获取一个网页
headers = {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/71.0.3578.98 Safari/537.36'
# "Cookie": 'Pycharm-26c2d973=dbb9b300-2483-478f-9f5a-16ca4580177;'
}
r = requests.get(
'https://www.amazon.com/s/ref=nb_sb_noss_2?__mk_zh_CN=亚马逊网站' +
'&url=search-alias%3Daps&field-keywords=' + keywords,
timeout=timeout,
headers=headers,
)
# 获取到内容
html_doc = r.text
# 然后创建一个bs-lxml解析器的对象
soup = BeautifulSoup(html_doc, "lxml")
request抓取容易被封锁, 解决反爬的基本措施
如果是动态网页使用Selenium抓取Ajax和动态HTML内容参考
由于Selenium间接调用本机ie/Firefox/chrome浏览器, 所以如果要调用chrome, 那么必须上谷歌主页下载与本机浏览器版本对应的driver(chromedriver.exe)
@module_description : selenium库调用谷歌无浏览器界面
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import os
root_path = os.path.abspath('.')
driver = ''
# 启动driver
def init_web_driver():
global driver
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
driver_path = root_path + '\\chromedriver.exe'
driver = webdriver.Chrome(
chrome_options=chrome_options, executable_path=driver_path)
# 关掉driver
def close_web_driver():
driver.quit()
@module_description : 主模块
chromeDriver.init_web_driver()
chromeDriver.driver.get(
'https://www.amazon.com/s/ref=nb_sb_noss_2?__mk_zh_CN=亚马逊网站' +
'&url=search-alias%3Daps&field-keywords=' + keywords)
time.sleep(1)
html_doc = chromeDriver.driver.page_source
chromeDriver.close_web_driver()
soup = BeautifulSoup(html_doc, "lxml")
提取数据
抓取到之后, 需要使用bs4-lxml进行数据提取
首先定位自己要爬取的内容所在位置
1、F12打开控制台点选元素定位
2、在目标网站上右键-- 查看源代码
1,2结合可以判断出当前要爬取的内容是否有唯一性, 例如: 标签是否唯一, css类名是否唯一, id是否唯一, 根据这些唯一性, 可以判断是否使用搜索文档树
或css选择器
来定位目标
另外, 不太建议单独使用bs4中遍历文档树的tag用法来定位爬取内容(复杂页面层级结构十分复杂混乱), 应该和
搜索文档树
结合, 当搜索定位到爬取内网父/祖 标签结构时, 可以使用tag进一步获取内容。
搜索文档树用法-find和find_all
find/find_all (name, attrs, recursive, text, **wargs) ---recursive 递归的,循环的
- 这些参数相当于过滤器一样可以进行筛选处理。
- 不同的参数过滤可以应用到以下情况:
name参数:查找标签
attrs参数:查找标签的属性
text参数:查找文本
keyword 参数
---如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来 搜索,例如包含一个名字为 id 的参数,Beautiful Soup会搜索每个tag的”id”属性.
注意: class 应写成 class_
正则表达式
如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容
@ 实例
div_all = soup.find_all(
name="div",
class_="a-row a-spacing-none scx-truncate-medium sx-line-clamp-2") //keyword
comment_star_str = goods_soup.find(
name="span", id="acrPopover").get('title')
soup.find_all(re.compile("^b")): //正则表达式
遍历文档树-tag用法
-
tag对应着html中每一个标签
-
每个tag都有自己的名字,通过 .name 来获取:tag.name
-
如果一个tag仅有一个子节点,那么这个tag也可以使用 .string 方法,输出结果标签内容。
-
可以使用 [父tag对象 . 子标签名] 来定位子标签
点取属性的方式只能获得当前名字的第一个tag
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b // 获取tap中第一个b标签
-
.contents 和 .children
tag的 .contents属性可以将tag的子节点以列表的方式输出:
通过tag的 .children 生成器,可以对tag的子节点进行循环: -
.contents 和 .children
-
tag属性访问
一个tag可能有很多个属性, tag的属性的操作方法与字典相同:
@ tag <b class="boldest"> 有一个 “class” 的属性,值为 “boldest” .
tag['class']
# u'boldest'
另外也可以通过get()方法来获取属性:
tag.get('class')
CSS选择器
Tag 或 BeautifulSoup 对象的 .select() 方法中传入字符串参数,即可使用CSS选择器的语法找到tag:
示例:
找到某个tag标签下的直接子标签 :
soup.select("p > a") //p下 的a标签
soup.select("p > #link1")//p下 的id为link1的标签
通过tag的id查找:
soup.select("#link1") //tag中id为link1的标签
通过属性的值来查找:
soup.select('a[href="http://example.com/elsie"]') //tag中href为example.com/elsie的a标签
网友评论