Python爬取哔哩哔哩视频的相关信息并保存到excel文档

利用自动化测试工具selenium自动搜索视频信息,自动翻页爬取搜索到的视频相关信息。
首先找到自己要爬取数据网页数据,如下
Python爬取哔哩哔哩视频的相关信息并保存到excel文档_第1张图片
整个流程如下:
1.声明浏览器对象
2.声明浏览器最长等待时间
3.创建excel文件对象
4.新建excel sheet页,并写入头部标签
5.浏览器访问网页地址
6.定位输入窗口,输入文字并回车跳转
7.切换到新标签页
8.等待网页数据加载完成
9.beautifulSoup解析网页数据
10.找到要爬取的数据,并保存到excel中
11.获取搜索到的最大页数
12.等待下一页按钮加载完成,并点击下一页按钮切换到下一页
13.重复8-10步和12步,直到所有页数爬取完毕

  1. 声明浏览器对象,并设置浏览器窗口大小
browser = webdriver.Chrome()
#browser = webdriver.PhantomJS()
browser.set_window_size(1400, 900)
  1. 创建excel文件
book = xlwt.Workbook(encoding='utf-8', style_compression=0)

sheet = book.add_sheet('蔡徐坤篮球', cell_overwrite_ok=True)
sheet.write(0, 0, '名称')
sheet.write(0, 1, '地址')
sheet.write(0, 2, '描述')
sheet.write(0, 3, '观看次数')
sheet.write(0, 4, '弹幕数')
sheet.write(0, 5, '发布时间')

在这里采用xlwt库对excel文件进行写入操作,xlwt库只能写入数据,无法读取数据

  1. 访问B站,并自动搜索,同时返回视频页数
def search():
    try:
        print('开始访问b站....')
        browser.get("https://www.bilibili.com/")
        
        search = browser.find_element_by_xpath('//div[@class="nav-search"]/form/input')
        search.send_keys("蔡徐坤 篮球")
        search.send_keys(Keys.ENTER)

        # 跳转到新的窗口
        print('跳转到新窗口')
        all_h = browser.window_handles
        browser.switch_to.window(all_h[1])

        html = browser.page_source
        # print(html)
        soup = BeautifulSoup(html, 'html.parser')
        save_to_excel(soup)

        total_index = soup.find(class_='page-item last').find(class_='pagination-btn')
        return int(total_index.text)
    except TimeoutException:
        return search()

3.1 打开浏览器,访问B站

	browser.get("https://www.bilibili.com/")

3.2 定位搜索框的位置,并填入要搜索的文本,并回车

 	search = browser.find_element_by_xpath('//div[@class="nav-search"]/form/input')
    search.send_keys("蔡徐坤 篮球")
    search.send_keys(Keys.ENTER)

selenium可以驱动浏览器代替人工完成各种操作,查找定位要操作的节点,填充数据,模拟点击,拖拽等
查找单个节点可以通过如下方法:
find_element_by_id 【通过元素的 id 来选择】
例:

test
,查找:driver.find_element_by_id(‘bdy-inner’)

find_element_by_name 【通过元素的 name 来选择】
例:,查找:driver.find_element_by_name(‘password’)

find_element_by_xpath 【通过 xpath 选择】
例:,查找:driver.find_element_by_xpath("//form[@id=‘loginForm’]")

find_element_by_link_text 【通过链接地址选择】
例:continue,查询:driver.find_element_by_link_text(‘continue’)

find_element_by_partial_link_text 【通过链接的部分地址选择】
例:continue,查询:driver.find_element_by_link_text(‘cont’)

find_element_by_tag_name 【通过元素的名称选择】
例:< h1>welcome< h1>,查询:driver.find_element_by_tag_name(‘h1’)

find_element_by_class_name 【通过元素的 class 选择】
例:< p class=“content”>welcome to TRHX’S BLOG!< /p>,查询:driver.find_element_by_class_name(‘content’)

find_element_by_css_selector 【通过元素的 class 选择】
例:< div class=‘bdy-inner’>test< /div>,查询:driver.find_element_by_css_selector(‘div.bdy-inner’)

find_element() 【通用方法,需要传递两个参数:查找方式 By 和值】
例:driver.find_element_by_id(‘inner’) 等价于 find_element(By.ID, inner),使用时需要from selenium.webdriver.common.by import By

selenium对浏览器的操作也可称之为节点交互,常用的节点交互方式有以下几种
send_keys:模拟按键输入
clear:清除元素的内容
click:单击元素
submit:提交表单

3.3 完成点击操作后,搜索结果会在新标签页中呈现,这时需要切换到新标签页中

	print('跳转到新窗口')
    all_h = browser.window_handles
    browser.switch_to.window(all_h[1])

3.4 获取第一页的视频相关信息,并保存到excel文档中

	html = browser.page_source
	# print(html)
	soup = BeautifulSoup(html, 'html.parser')
	save_to_excel(soup)

这里采用beautifulSoup库对网页数据进行解析。
常用的解析器有四种,如下:

解析器 使用方法
Python 标准库 BeautifulSoup(markup, “html.parser”)
LXML HTML 解析器 BeautifulSoup(markup, “lxml”)
LXML XML 解析器 BeautifulSoup(markup, “xml”)
html5lib BeautifulSoup(markup, “html5lib”)

3.5 返回搜索结果的页数

	total_index = soup.find(class_='page-item last').find(class_='pagination-btn')
	return int(total_index.text)

这里利用beautifulSoup解析器提取名为page-item last的class节点下的pagination-btn节点文本数据,得到总的搜索页数
4. 点击下一页按钮,并爬取下一页视频信息保存

WAIT = WebDriverWait(browser, 20)
def next_page(page_num):
    try:
        print('获取第(%d)页数据' % page_num)
        next_btn = WAIT.until(EC.element_to_be_clickable((By.CSS_SELECTOR,
                                                          'li.page-item.next > button')))
        next_btn.click()
        get_source()
    except TimeoutException:
        browser.refresh()
        return next_page(page_num)

引入 WebDriverWait 对象,指定最长等待时间,这里最长等待时间20秒,调用它的 until() 方法,传入要等待条件 expected_conditions。比如,这里传入了 element_to_be_clickable这个条件,代表节点被选中,并可以被点击的时候
4.1 定位下一页按钮位置,并发送点击事件切换到下一页

 print('获取第(%d)页数据' % page_num)
        next_btn = WAIT.until(EC.element_to_be_clickable((By.CSS_SELECTOR,
                                                          'li.page-item.next > button')))
        next_btn.click()

4.2 切换到下一页后,等待ul.video-list.clearfix节点出现,再获取界面数据,爬取视频信息

def get_source():
    WAIT.until(EC.presence_of_element_located(
        (By.CSS_SELECTOR, 'ul.video-list.clearfix')))
    # browser.refresh()
    html = browser.page_source
    # print(html)
    soup = BeautifulSoup(html, 'html.parser')
    save_to_excel(soup)

5.最后,保存爬取到的结果

def save_to_excel(soup):
    list = soup.find(class_='video-list clearfix').find_all_next(class_='info')

    for item in list:
        item_title = item.find('a').get('title')
        item_link = item.find('a').get('href')
        item_dec = item.find(class_='des hide').text
        item_view = item.find(class_='so-icon watch-num').text
        item_biubiu = item.find(class_='so-icon hide').text
        item_date = item.find(class_='so-icon time').text

        print('爬取:' + item_title)

        global n

        sheet.write(n, 0, item_title)
        sheet.write(n, 1, item_link)
        sheet.write(n, 2, item_dec)
        sheet.write(n, 3, item_view)
        sheet.write(n, 4, item_biubiu)
        sheet.write(n, 5, item_date)

        n = n + 1

提取到名为视频信息节点名为video-list clearfix的class节点的所有下一级名为info的class节点信息后,在提取各个信息存入excel
6.完整代码如下

from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import xlwt
import time

browser = webdriver.Chrome()
#browser = webdriver.PhantomJS()
WAIT = WebDriverWait(browser, 20)
browser.set_window_size(1400, 900)

book = xlwt.Workbook(encoding='utf-8', style_compression=0)

sheet = book.add_sheet('蔡徐坤篮球', cell_overwrite_ok=True)
sheet.write(0, 0, '名称')
sheet.write(0, 1, '地址')
sheet.write(0, 2, '描述')
sheet.write(0, 3, '观看次数')
sheet.write(0, 4, '弹幕数')
sheet.write(0, 5, '发布时间')

n = 1


def search():
    try:
        print('开始访问b站....')
        browser.get("https://www.bilibili.com/")

        search = browser.find_element_by_xpath('//div[@class="nav-search"]/form/input')
        search.send_keys("蔡徐坤 篮球")
        search.send_keys(Keys.ENTER)

        # 跳转到新的窗口
        print('跳转到新窗口')
        all_h = browser.window_handles
        browser.switch_to.window(all_h[1])

        html = browser.page_source
        # print(html)
        soup = BeautifulSoup(html, 'html.parser')
        save_to_excel(soup)

        total_index = soup.find(class_='page-item last').find(class_='pagination-btn')
        return int(total_index.text)
    except TimeoutException:
        return search()


def next_page(page_num):
    try:
        print('获取第(%d)页数据' % page_num)
        next_btn = WAIT.until(EC.element_to_be_clickable((By.CSS_SELECTOR,
                                                          'li.page-item.next > button')))
        # time.sleep(5)
        next_btn.click()
        get_source()
    except TimeoutException:
        browser.refresh()
        return next_page(page_num)


def save_to_excel(soup):
    list = soup.find(class_='video-list clearfix').find_all_next(class_='info')

    for item in list:
        item_title = item.find('a').get('title')
        item_link = item.find('a').get('href')
        item_dec = item.find(class_='des hide').text
        item_view = item.find(class_='so-icon watch-num').text
        item_biubiu = item.find(class_='so-icon hide').text
        item_date = item.find(class_='so-icon time').text

        print('爬取:' + item_title)

        global n

        sheet.write(n, 0, item_title)
        sheet.write(n, 1, item_link)
        sheet.write(n, 2, item_dec)
        sheet.write(n, 3, item_view)
        sheet.write(n, 4, item_biubiu)
        sheet.write(n, 5, item_date)

        n = n + 1


def get_source():
    WAIT.until(EC.presence_of_element_located(
        (By.CSS_SELECTOR, 'ul.video-list.clearfix')))
    # browser.refresh()
    html = browser.page_source
    # print(html)
    soup = BeautifulSoup(html, 'html.parser')
    save_to_excel(soup)


def main():
    try:
        total = search()
        # print(total)

        for i in range(2, int(total)+1):
            next_page(i)

    finally:
        browser.close()
        browser.quit()


if __name__ == '__main__':
    main()
    book.save(u'蔡徐坤篮球.xls')

最后将excel文档保存为xls格式,在有的电脑上面保存为xlsx格式时,本地打开文档出现格式错误的问题,将保存格式更改为xls可以解决该问题。

你可能感兴趣的:(python3,爬虫)