B站美食视频爬取教程 - 使用Selenium和BeautifulSoup解析网页数据
本教程将教你如何使用Selenium和BeautifulSoup库爬取B站美食视频数据,并将其保存为CSV文件。
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()
这个错误是超时异常,可能是因为页面加载时间过长或者网络不稳定导致的。可以尝试增加等待时间或者使用其他浏览器驱动,比如Chrome或Firefox。同时,也可以检查网络连接是否正常,或者尝试在其他时间段进行爬取。
解决方法:
- 增加等待时间: 在
WAIT = WebDriverWait(browser,10)中,将等待时间10秒增加到更长的时间,例如20秒或30秒。 - 使用其他浏览器驱动: 尝试使用Chrome或Firefox浏览器驱动,例如
webdriver.Chrome()或webdriver.Firefox()。 - 检查网络连接: 确保网络连接正常,并且网络速度稳定。
- 尝试在其他时间段进行爬取: 如果网络流量较大,会导致页面加载时间过长,可以尝试在非高峰时段进行爬取。
其他建议:
- 使用代理服务器可以提高爬取效率。
- 设置合理的爬取频率,避免对目标网站造成过大的压力。
- 使用异常处理机制,防止程序意外终止。
注意:
- 爬取网页数据时请遵守目标网站的robots.txt协议,不要过度爬取。
- 爬取数据需要谨慎,避免侵犯他人的隐私或造成不良影响。
原文地址: https://www.cveoy.top/t/topic/oJOZ 著作权归作者所有。请勿转载和采集!