soup = BeautifulSoup(rep,"lxml")报错bs4.FeatureNotFound: Couldn’t find a tree builder with the features you requested: html_parser.
解决方案:安装lxml
第一步是建立BeautifulSoup对象,这个对象在bs4模块中。在建立对象的时候可以额外指定一个参数,作为实际的HTML解析器。解析器的值可以指定html.parser,这是内置的HTML解析器。更好的选择是使用lxml解析器,纯C语言实现,速度会更快。如果使用lxml需要安装lxml包,不然会报上面的错误。
鉴于上述两种方法的缺点,采用pyppeteer进行抓包,是 Puppeteer 的 Python 版本的实现,由一位来自于日本的工程师依据 Puppeteer 的一些功能开发出来的非官方版本。 在 Pyppetter 中,实际上它背后也是有一个类似 Chrome 浏览器的 Chromium 浏览器在执行一些动作进行网页渲染。Chromium 是谷歌为了研发 Chrome 而启动的项目,是完全开源的。二者基于相同的源代码构建,Chrome 所有的新功能都会先在 Chromium 上实现,待验证稳定后才会移植,因此 Chromium 的版本更新频率更高,也会包含很多新的功能,但作为一款独立的浏览器,Chromium 的用户群体要小众得多。两款浏览器 “同根同源”,它们有着同样的 Logo,但配色不同,Chrome 由蓝红绿黄四种颜色组成,而 Chromium 由不同深度的蓝色构成。参考链接
from pyppeteer import launch
def crawl(url):
browser = await launch(options={'args': ['--no-sandbox']}) # 创建浏览器对象
page = await browser.newPage() #新建标签页
await page.goto(url,{'timeout': 1000*60}) #根据url获取页面相应内容
rep = await page.content() # 爬取整个网页数据
print(rep) #打印出来的就是一个HTML
await browser.close()
使用Beautiful Soup4定位网页元素,方便我们获取想要的信息,后面简称bs4。
主要用到bs4的两个函数,一个find会找到出现的首个满足条件的元素;findAll找到所有满足条件的元素。在实际应用中可以灵活运用。这两个函数可以只传一个参数如soup.find(‘title’),即找到rep中的title标签。但是对于一些标签有多个,比如ul有两个的情况下,可以荣归class加以区分,即soup.find(‘ul’,class_=“list1”)即可定位到第一个ul。
soup.title.string直接获取文本“Testing”soup.h2.get_text()获取文本内容“I am embbed"
soup.find('ul',class_="list1").findAll('li')这样我们可以得到list1下的两个li标签。想进一步获取特定li标签的内容,如果有可以唯一标识的,就在find参数里加上唯一属性;如果没有,也可以按照在列表中的相对位置,通过索引获取文本内容。from bs4 import BeautifulSoup
rep = '''Testing
I am embbed
...
- 列表1第1项
- 列表1第2项
文字1
文字2
- 列表2第1项
- 列表2第2项
'''
def bs4_use(url):
soup = BeautifulSoup(rep, "lxml") #创建一个beautiful soup对象,html解释器选择lxml,req为爬取的网页信息
#soup = BeautifulSoup(open("index.html"), "lxml") #打开本地html文件创建bs4对象
print(soup.title)
print(soup.find('title').get_text())
首先我们通过检查,先查看需要定位内容在HTML中的标签属性,相对位置,可以看到

上面分析,根据ID定位元素代码复用性几乎是0,所以我们需要看网页的整体布局,下图中左边是源码,右边是页面布局,可以看到不同版本其实是依次排序的,即一个h3后面2-3个p标签为一个版本,后面又是一个h3标签接2-3个p标签。。依次直到所有的版本列举完。这些不同的版本中有着异同点,可以根据异同点来定位。

安装包:bs4、pyppeteer
版本号:因为最新版本一定是在最上面,所以我们找到的第一个h3标签就是最新版本的版本号。(这里的前提是前面没有出现h3标签)
其他信息
import asyncio
from pyppeteer import launch
from bs4 import BeautifulSoup
async def main(url):
browser = await launch(options={'args': ['--no-sandbox']}) # 使用pyppeteer静态/动态网页都可成功爬取
page = await browser.newPage()
await page.goto(url,{'timeout': 1000*60})
await asyncio.sleep(15)
rep = await page.content() # 爬取到整个网页数据,接下来可用 正则/BeautifulSoup 就可以抓取数据
soup = BeautifulSoup(rep, "lxml")
latest_version = soup.h3.get_text()
other_msg = soup.findAll('p')
#find the latest update date
for index,item in enumerate(other_msg):
if '更新日期' in item.get_text():
date = item.get_text().split(':')[-1]
break
#find the second update date and locate the uopdated meaasge of the latest version
for i in range(index+1,index+4):
if '更新日期' in other_msg[i].get_text():
break
update_msg = other_msg[i-1].get_text()
print(latest_version)
print(date)
print(update_msg)
await browser.close()
if __name__ == '__main__':
url = 'https://opendocs.alipay.com/open/02no45' # 爬取的网址
asyncio.get_event_loop().run_until_complete(main(url))