本文最后更新于 123 天前,其中的信息可能已经有所发展或是发生改变。
听说Python很适合写爬虫,于是我就花了两个晚上稍微学了学Python,现在差不多入门了,就先写个简单的爬虫试试,爬一下B站的热榜。
这里用到了selenium和xlwt两个库,主要是用于模拟浏览器和写入电子表。
因为传统获取网页源代码的方式已经不适用于动态渲染的网页了,所以需要模拟浏览器访问,然后再用审查元素找出页面中的信息。原理就这么简单,那么就开灶吧。
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
url = "https://www.bilibili.com"
browser.get(url)
先来测试一下浏览器能否正常打开
已经出现了”Chrome正受到自动测试软件的控制”,说明这时候模拟就已经生效了,那么接下来就是要进到热门页面去爬取数据了。
这里其实可以直接打开热门页面,不必先打开B站再模拟点击
接下来就是要控制浏览器模拟点击热门标签然后将标签页切换到新页面。
homePageItems = browser.find_elements(By.CLASS_NAME, "channel-icons__item")
for btn in homePageItems:
if (btn.find_element(By.CLASS_NAME, "icon-title").text == "热门"):
btn.click()
break
# 等待页面加载完成后再切换到新标签页
time.sleep(2)
handles = browser.window_handles
for ha in handles:
# 切换到新页面
browser.switch_to.window(ha)
if (browser.title == "哔哩哔哩热门"):
...
现在已经成功进到热门页面了,接下来就是数据获取了。
if (browser.title == "哔哩哔哩热门"):
# 这一行用于向下滚动页面
# roll_window_to_bottom(browser, stop_length=2000, step_length=500)
hotVideos = browser.find_elements(By.CLASS_NAME, "video-card")
videosList = []
for card in hotVideos:
cardInfo = card.find_element(By.CLASS_NAME, "video-card__info")
cardContent = card.find_element(By.CLASS_NAME, "video-card__content")
title = cardInfo.find_element(By.CLASS_NAME, "video-name")
upName = cardInfo.find_element(By.CLASS_NAME, "up-name")
plays = cardInfo.find_element(By.CLASS_NAME, "play-text")
danmaku = cardInfo.find_element(By.CLASS_NAME, "like-text")
url = cardContent.find_element(By.TAG_NAME, "a")
coverImage = url.find_element(By.CLASS_NAME, "cover-picture__image")
现在我们就已经获取到各视频的信息了,接下来就是要把它们整合一下了。
现在还有一个小问题,这样获取到的只是显示在页面上的视频,向下滚动还可以继续加载更多,所以我们要先模拟滚动到最底部,然后再获取数据。
所以定义一个新函数(roll_window_to_bottom)用于滚动页面:
def roll_window_to_bottom(browser, stop_length=None, step_length=500):
"""selenium 滚动当前页面,向下滑
:param browser: selenium的webdriver
:param stop_length: 滑动的最大值
:param step_length: 每次滑动的值
"""
original_top = 0
while True: # 循环向下滑动
if stop_length:
if stop_length - step_length < 0:
browser.execute_script("window.scrollBy(0,{})".format(stop_length))
break
stop_length -= step_length
browser.execute_script("window.scrollBy(0,{})".format(step_length))
time.sleep(0.5 + random.random()) # 停顿一下
check_height = browser.execute_script(
"return document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;")
if check_height == original_top: # 判断滑动后距顶部的距离与滑动前距顶部的距离
break
original_top = check_height
这一段代码来自呆萌的代Ma的博客_CSDN博客-python,数据处理,运维领域博主,偷个小懒。
然后直接调用就可以了,将上方的注释删掉即可。
最后我们把爬到的数据写出到一张电子表里面:
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('B站热门')
worksheet.write(0, 1, '视频标题')
worksheet.write(0, 2, 'UP主')
worksheet.write(0, 3, '播放量(万)')
worksheet.write(0, 4, '弹幕数')
worksheet.write(0, 5, '视频封面')
worksheet.write(0, 6, 'URL')
index = 1
for v in newVideosList:
worksheet.write(index, 0, index)
worksheet.write(index, 1, v.title)
worksheet.write(index, 2, v.upName)
worksheet.write(index, 3, v.plays)
worksheet.write(index, 4, v.comments)
worksheet.write(index, 5, v.coverImage)
worksheet.write(index, 6, v.url)
index = index + 1
workbook.save('.\爬虫结果.xls')
tql
大佬好qwq
tql,是大佬