简直太好用了!!
- playwright:动态页面爬取,执行如页面导航、获取元素HTML这些功能,可用模仿操作行为
- BeautifulSoup:解析静态页面,特点是可用按顺序解析HTML元素,如文章页面,一般很多都是一个段落一个
<p></p>
标签包裹的,中间还包括图片、表格等等。把通过playwright获取到的页面内容塞给BeautifulSoup,按顺序解析
来一个简单的示例:
- playwright获取动态页面
async def page_crawler(url: str, logger) -> (int, dict):
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url)
# 获取要解析的HTML内容,这里也可用是一个page的全部元素
info_html = await page.locator('div.con-bd ').inner_html()
# 执行页面解析
result = await process_element(info_html)
return result
- BeautifulSoup解析
# 定义一个函数来处理div中的所有子孙元素
def process_element(element):
if element is None:
return ''
result = ''
# 解析标签
if element.name == 'p':
# 判断<p>标签内是否包含<img>标签,并获取src属性
img_tag = element.find('img')
if img_tag:
result += f"'\n'{img_tag['src']}"
result += f"'\n'{element.get_text()}"
# 解析img标签
elif element.name == 'img':
print(f"Image source: {element['src']}")
result += f"'\n'{element['src']}"
# 解析 a 标签
elif element.name == 'a':
print(f"Link URL: {element['href']}")
result += f"'\n'{element['href']}"
# 指定的dom元素特别处理
elif element.name == 'div' and element.get('name') == 'class-name':
result += f"\n{element.find('h2').get_text()}"
# 解析表格
elif element.name == 'table':
# 提取表头
headers = [th.get_text() for th in element.find_all('th')]
# 提取表格内容
rows = []
rows.append(headers)
for row in element.find_all('tr')[1:]: # 跳过表头行
cells = [cell.get_text() for cell in row.find_all('td')]
rows.append(cells)
result += str(rows)
# 解析列表
elif element.name == 'ul':
# 获取所有li标签并打印其内容
for li in element.find_all('li'):
# result += li.get_text(strip=True)
# 获取li标签内的所有文本
text = li.get_text(separator=" ", strip=True) if li else ''
result += text
# 获取li标签内的所有图片src,如果没有img标签返回空列表
images = [img['src'] for img in li.find_all('img')] if li and li.find_all('img') else []
result += str(images)
# 递归处理当前元素的所有子元素
for child in element.children:
if child.name: # 只处理标签元素,忽略字符串等非标签内容
result += process_element(child)
return result
- 以上方法还可以简化;
- 解析的页面元素还不全;
- 代码部分可用复用,但一般页面不会完全一样,所以使用时也需要修改