Bilibili 美食视频爬取:代码解析及常见错误处理
本篇文章将深入讲解如何使用Python爬取Bilibili美食视频信息,包括代码实现、常见错误处理及优化建议,并提供实用技巧帮助您轻松获取所需数据。
代码解析
import requests
from bs4 import BeautifulSoup
from selenium import webdriver # 引入浏览器驱动
from selenium.webdriver.common.by import By # 借助By模块进行操作
from selenium.webdriver.support.ui import WebDriverWait # 显式等待
from selenium.webdriver.support import expected_conditions as Ec # 显式等待的条件
from selenium.common.exceptions import TimeoutException # 捕获超时异常
import pandas as pd
browser = webdriver.Edge() # 获取浏览器对象
WAIT = WebDriverWait(browser,10) # 指定最长等待时间
url = 'https://www.bilibili.com'
print('开始访问b站……')
browser.get(url)
def search(content):
print('正在进行搜索……')
# 用XPath选取节点
input = WAIT.until(Ec.presence_of_element_located((By.XPATH,'//*[@id="nav_searchform"]/input')))
submit = WAIT.until(Ec.element_to_be_clickable((By.XPATH,'//*[@id="nav_searchform"]/div/button')))
# 从搜索框输入并点击搜索
input.send_keys(content)
submit.click()
def crawl():
htmls = [] # 存放每个页面的HTML
# 用for循环爬取每一个页面并获得其HTML
for i in range(5):
# 用f+字符串来表示每一个页面的网址
url = f"https://search.bilibili.com/all?keyword=%E5%8D%8E%E6%99%A8%E5%AE%87&from_source=nav_search_new&page={str(int(i+1))}"
r = requests.get(url) # 返回Response对象
if r.status_code != 200: # 状态码检测
raise Exception("error")
htmls.append(r.text) # r.text是字符串类型
return htmls
def parse(htmls):
videos = [] # 存放每个视频解析出来的HTML
print('解析页面中……')
for html in htmls:
soup = BeautifulSoup(html, 'html.parser') # 解析每个页面
# 获取每个视频的标签树
video = soup.find(class_="video-list clearfix").find_all(class_="video-item matrix")
videos.extend(video) # 列表存入列表,所以用extend()函数
items = [] # 存放每个视频的各个项目
print('正在爬取相关信息……')
for video in videos:
item = {} # 每个字典存放每个视频的相关信息
item['标题'] = video.find('a')['title'] # 获取标签属性
item['总播放数'] = video.find(class_='bili-video-card__stats--item').get_text()
item['总弹幕数'] = video.find(class_='bili-video-card__stats--item').get_text() # 获取NavigableString
item['发布时间'] = video.find(class_='bili-video-card__info--date').get_text() # 获取目标路径下的子孙字符串
item['发布者'] = video.find(class_='bili-video-card__info--author').get_text()
item['链接'] = video.find('a')['href'] # 获取视频链接
# 访问链接爬取更多数据
response = requests.get(item['链接'])
soup = BeautifulSoup(response.text, 'html.parser')
item['点赞数'] = soup.find(class_='video-like-info video-toolbar-item-text').get_text()
item['金币数'] = soup.find(class_='video-coin-info video-toolbar-item-text').get_text()
item['收藏量'] = soup.find(class_='video-fav-info video-toolbar-item-text').get_text()
item['分享数'] = soup.find(class_='video-share-info-text').get_text()
item['视频介绍'] = soup.find(class_='desc-info-text').get_text()
item['标签'] = soup.find(class_='tag-area clearfix').get_text()
item['评论数'] = soup.find(class_='total-reply').get_text()
items.append(item) # 将该视频的信息添加到列表中
return items
def save_to_csv(items):
print('成功将数据写入文件!')
# 将爬取的数据写入csv文件
df = pd.DataFrame(items) # 用DataFrame构造数据框
df.to_csv("美食.csv")
def main():
try:
search('美食')
htmls = crawl()
items = parse(htmls)
save_to_csv(items)
finally:
print('爬取信息成功!')
browser.close()
if __name__ == '__main__':
main()
常见错误处理
错误信息:selenium.common.exceptions.TimeoutException: Message: ...
原因:网页元素加载过慢或定位不准确导致找不到指定元素。
解决方法:
- 增加等待时间:使用显式等待,增加等待时间,等待页面元素加载完成再进行操作。
input = WAIT.until(Ec.presence_of_element_located((By.XPATH,'//*[@id="nav_searchform"]/input'),timeout=20))
-
修改元素定位方式:尝试使用其他元素定位方式,例如id、class等,或者修改XPath表达式,以确保准确定位到目标元素。
-
使用隐式等待:设置全局等待时间,在页面加载时等待一段时间。
browser.implicitly_wait(10) # 等待10秒
- 增加异常处理:捕获可能出现的TimeoutException异常,避免程序崩溃。
try:
input = browser.find_element_by_xpath('//*[@id="nav_searchform"]/input')
except TimeoutException:
print('元素定位超时!')
优化建议
- 使用代理:避免被网站识别为爬虫,提高爬取效率。
- 使用多线程:利用多线程提高爬取速度。
- 数据存储:将爬取的数据存储到数据库中,方便后续分析和使用。
总结
本文详细介绍了Bilibili美食视频爬取的代码实现和常见错误处理方法,并提供了优化建议。希望本文能够帮助您更好地理解和应用爬虫技术,并成功获取所需数据。
原文地址: https://www.cveoy.top/t/topic/oJPa 著作权归作者所有。请勿转载和采集!