0


基于selenium的视频爬取

基于selenium的视频爬取项目


前言

本项目为本人今年爬虫课程的期末程序设计,为记录自己的学习过程,故将项目发表在博客,以便自己日后回顾


一、selenium是什么?

Selenium是一个用于自动化web浏览器操作的开源工具套件。它支持各种浏览器(包括Chrome、Firefox、Safari等),允许用户编写脚本来模拟用户与web页面的交互,如点击按钮、填写表单、滚动页面等。Selenium主要用于web应用程序的测试,但也可以用于其他目的,如网络爬虫、自动化数据收集等。


二、项目步骤

1.引入库

项目需要的库

import random
import re
import threading
import requests  # 导入requests模块import pymysql # 使用mysql数据库import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.options import Options

from proxy_ip.tool import readaproxy 
# 此处引入为自己创建的一个获取代理ip的函数

2.网页分析

通过开发者工具调试网页,发现视频数据在一个Ajax发送链接返回的json结果中。

在这里插入图片描述

在这里插入图片描述
故现在思路确定:通过request.get()向该Ajax的url发送请求获取到数据,再通过解析数据,拼凑出视频链接的url(视频链接为,https://www.dongchedi.com/video/ + json的data[‘data’][‘news’][页数][‘unique_id_str’]构成),最后通过selenium访问该url获取到数据进行本地下载,并将视频详细数据存储在数据库中。

3.selenium爬取方法的设计

其中使用无头,禁止图片css加载和禁用gpu是为了加快selenium运行速度。

defseleunim_(url, title):'''
    用于自动化获取视频链接并下载到本地video文件夹中
    :param url: 爬取网址
    :param title: 视频标题
    :return:
    '''# 创建Chrome浏览器选项对象
    opt = Options()# 使用无头模式
    opt.add_argument('--headless')# 禁止图片和css加载
    prefs ={"profile.managed_default_content_settings.images":2,'permissions.default.stylesheet':2}
    opt.add_experimental_option("prefs", prefs)

    opt.add_argument("--disable-gpu")# 禁用gpu 
    pa = webdriver.Chrome(options=opt)# 开始
    pa.get(url)
    pa.delete_all_cookies()# 删除网页之前的cookie

    time.sleep(0.7)print(f'正在下载{title}')
    element = pa.find_element(By.XPATH,"/html/body/div[1]/div/div/div/div/div[1]/div[1]/div/div[1]/div/div/div/video")# 找到视频链接元素
    result = requests.get(element.get_attribute('src'))# 对标题进行处理 防止打开文件时出错
    title = sanitize_filename(title)# 保存视频链接到文件中withopen(f"video/{title}.mp4","wb")as f:
        f.write(result.content)print('-------'+ title +'----下载成功')
    pa.quit()

为了防止标题出现非法的字符导致保存文件出现错误,对标题进行预处理。

defsanitize_filename(title):# 使用正则表达式来匹配并移除非法字符
    sanitized = re.sub(r'[\\/*?"<>|:#.?\x00-\x1f]','', title)# 移除空格
    sanitized = sanitized.replace(' ','')# 去除字符串两端的空白字符(包括空格、制表符、换行符等)
    sanitized = sanitized.strip()# 确保文件名不会过长
    max_length =255# 例如,Windows中某些文件系统的最大路径长度为260个字符,文件名长度会受此限制

    sanitized = sanitized[:max_length]return sanitized

4.数据库相关的准备

创建一个简单的表,其中:
detail_context:视频详细内容
title:视频标题
num:数据编号(唯一性)

在这里插入图片描述

插入数据库的方法设计。

definsert(context, title):# 设置布尔标记,成功返回1,失败返回0
    tag =1

    db = pymysql.connect(
        host='localhost',
        user='root',
        password='liweijiaw',
        port=3306,
        db='dongchedi_vediodata')# 数据库信息

    cursor = db.cursor()# 启动数据库引擎
    sql ='INSERT INTO vedio_data (detail_context,title) VALUES ("%s","%s");'try:
        cursor.execute(sql,(context, title))# 执行sql语句
        db.commit()except pymysql.Error as e:print(e.args[0], e.args[1])
        db.rollback()# 回滚print('数据库fail')
        tag =0# 失败设置0

    db.close()return tag

5.主函数设计

最大特点是使用了多线程爬取,这样一次性就可以下载多个视频,提高爬取效率。

if __name__ =='__main__':# 响应头池
    headers_stack =["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36","Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50","Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50","Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0"]# 找到ajax发送的url,
    url =('https://www.dongchedi.com/motor/pc/content/get_static?''aid=1839&app_name=auto_web_pc&count=100&channel=news&page=1&article_type=video')# 随机获取一个User-Agent
    headers ={"User-Agent": headers_stack[random.randint(0,4)]}# 随机从数据库中获取一个可用的代理ip
    proxy ={"http": readaproxy()[0]}# 解析返回的数据包 (数据包是json格式)
    response = requests.get(url, headers=headers, proxies=proxy, timeout=3)
    data = response.json()# 解析json文件for i inrange(1,6):# 1 to 6 exclude 6.# 内容(将字典转为string类型,以免发生不必要的错误)
        context =str(data['data']['news'][i])# 解析获取标题
        title =str(data['data']['news'][i]['title'])# 插入数据库if insert(context, title)==0:print(f'{title}插入失败!')# 获取视频链接
        vedio_url =str(('https://www.dongchedi.com/video/'+ data['data']['news'][i]['unique_id_str']))while threading.active_count()>4:# 限制一次性只能下载四个视频,当大于四个视频在下载时,会卡在循环里等待print(f'当前正有{threading.active_count()-1}个视频在下载,等待中.......')# -1代表不包括主进程
            time.sleep(8)# 获取视频(通过观察发现视频页面为为https://www.dongchedi.com/video+"unique_id_str")由于网页是动态加载的,所以使用selenuim获取
        thread = threading.Thread(target=seleunim_, args=(vedio_url, title))# 使用多线程技术,一次性爬取多个视频
        thread.start()print('线程启动')

        time.sleep(0.5)# 这里休眠的作用是因为如果循环太快,将会大于四个线程被启动(循环的速度大于while判断的速度)

6.项目运行展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

标签: selenium

本文转载自: https://blog.csdn.net/qq_57232995/article/details/139836494
版权归原作者 brigee 所有, 如有侵权,请联系我们删除。

“基于selenium的视频爬取”的评论:

还没有评论