天天看点

selenium自动化案例(一)B站专栏爬虫写在前面案例分析代码实现

文章目录

  • 写在前面
  • 案例分析
  • 代码实现

写在前面

前几天学习了selenium自动化以及CSS、Xpath元素定位,想着找个网站练练手,不用登录的B站就是个不错的选择,下面以B站的校园学习专栏为例进行视频标题及外链信息的爬取。

测试环境

Windows 10 x64

Python 3.6.8

VS code

案例分析

  • 第一步当然是查看关键信息的定位,这里直接右键复制Xpath就OK,不过也需要思考Xpath的对应变化,比如翻页后哪些值变了而哪些值不变,找到翻页后的规律就能顺利写代码了。
  • 接下来需要考虑翻页的实现,我一开始考虑的是从url入手,但是采用selenium的话会很浪费资源,于是就选择页面内翻页,这里就要想想具体怎么实现了。下面代码中的

    page_plus_1()

    函数是我的直接思路,就是直接用Xpath定位,但是在抓取到第五页时候其标签就发生变化了(采用标签序号定位稳定性较差),于是我直接定位网页中的页面跳转输入框,每次页码增1,就可以了。
  • 最后,是循环的处理,这里我用了while循环并设置跳出条件,内部嵌套了每一页的条目循环,感觉还可以提高代码运行效率,不过作为小白的我还是先打好基础吧。

不得不说selenium库的封装还是很便携的,除了Xpath要费点事,剩下的都可以直接调用现成的方法。下面是代码的具体实现。

代码实现

# 用于设置强制等待
from time import sleep
# 浏览器自动化引擎
from selenium import webdriver

def web_auto_gain_item(page_num, item_num):
    # 每一页显示20个条目
    # 定位待抓取文字
    elems_title = driver.find_elements_by_xpath(
       '//*[@id="videolist_box"]/div[2]/ul/li[%d]/div/div[2]/a'%(item_num)
        )
    for elem in elems_title:
        # 抓取内容为:视频标题及外部链接(需要读取属性值)
        content = elem.text + ': ' + elem.get_attribute("href") + '\n'
        # 存储内容至文本文件,设置编码以存储文本字符串
        with open('bilibili_tech_list.txt', 'a', encoding='utf-8') as file:
            file.write(content)
        print(content)
    if item_num==20:
        print("第%d页抓取完成\n"%(page_num)+'-'*30)
        sleep(1)

def page_plus_1(page_num):
    # 定位翻页按钮,进行翻页操作
    # 第一页的翻页位于li[7], 之后的翻页位于li[8]
    # (但是由于使用数字定位标签,导致其鲁棒性不高,所以下面考虑第二种办法)
    if page_num==1:
        # 点击翻页
        driver.find_element_by_xpath(
            '//*[@id="videolist_box"]/div[2]/div[2]/ul/li[7]/button'
            ).click()
    else:
        driver.find_element_by_xpath(
            '//*[@id="videolist_box"]/div[2]/div[2]/ul/li[8]/button'
            ).click()

def page_plus_2(page_num):
    # 定位元素:网页翻页的
    driver.find_element_by_xpath(
        '//*[@id="videolist_box"]/div[2]/div[2]/div/input'
        ).send_keys('%d\n'%(page_num+1))


if __name__ == '__main__':

    # 待抓取的链接
    url = '''https://www.bilibili.com/v/technology/campus/#
    /all/stow/0/1/2020-08-07,2020-08-14'''
    # 实例化自动化引擎
    driver = webdriver.Edge(r"C:\msedgedriver.exe")
    driver.get(url)
    # 设置隐性等待
    driver.implicitly_wait(15)
    # 开始抓取
    while True:
        # 强制等待1s,便于读取页码信息
        sleep(1)
        page_num = eval(driver.current_url.split("/")[-2])
        print("开始抓取第%d页"%(page_num))

        # 循环提取item信息
        for item_num in range(1,21):
            web_auto_gain_item(page_num, item_num)

        # 抓取一页完成后进行翻页
        page_plus_2(page_num)

        # 设置循环跳出的条件,这里以抓取5页,20*5=100条视频信息为例
        if page_num == 5:
            print("抓取完毕,关闭浏览器,谢谢使用!")
            # 关闭浏览器,释放内存
            driver.close()
            break