爬虫学习日记之Python selenium

一 .问题概述

  在用requets抓取网页时,发现爬取网页源代码与网页开发者工具中的源代码不一样,无法获取有效的视频信息和url值,这是因为js代码动态加载的原因。如果想通过下载理解它网页的js代码而获得有用信息实在是太麻烦,但是可以用python的selenium轻松解决动态加载的问题。(本文章仅供学习  相关学习代码已经上传我的 gitee库

二.实现步骤

1 准备工具

  selenium包 re包 request包

2 分析网页

  动漫的视频播放器有一个点就是当你右键点击会有视频的统计信息。

当你点击它就会弹出一个小窗里面有视频的地址信息,这时候f12检查网站源代码,就能找到看见其视频地址 ,如果没有点击其网页源代码却是空的。

 

 所以如何实现网站自动点击,并获取其地址呢?这时我们就可以用到selenium的webdriver。关于下载浏览器对应的webdriver软件,可自行百度下载安装,在这不必赘述。

3 代码实现

要获得视频信息的弹窗,就要先找到视频统计信息,要找到视频统计信息就要先找到视频窗口。因此可以分为五步:定位视频窗口位置、右键点击视频窗口、点击统计信息、获取网页代码、提取url并下载。

 3.1 定位视频窗口

我们用selenium的find_element方法来完成定位。为了方便寻找定位我并没有在原网页中寻找定位,而是在播放器网页中寻找,播放器网页url可以在原网页中找到(如下),可以用requests得到。

 进入播放器网页,f12进入开发者工具,用ctrl+shift+c检查网页元素,点击视频界面就能得到其在源代码的位置,右键点击复制xpath地址,就可以定位位置了。并通过move_to_element()模拟鼠标移动到定位位置。

e = browser.find_element('xpath', '//*[@id="lelevideo"]')
action.move_to_element(e).perform()

3.2 右键点击视频窗口、点击统计信息

context_click()和click分别模拟点击右键点击和左键点击,定位视频统计信息按钮同上理。

action.context_click(e).perform()
e = browser.find_element('xpath', '//*[@id="player"]/div[9]/div[1]/a')
action.click(e).perform()

3.3获取网页代码、提取url并下载

page_sorce可以直接获取当前网页的源代码,再通过re的findall()找到所需要的url,就可以通过get方法获得数据信息,存进文件就行。

text = browser.page_source
# print(text)
url_data = re.findall('视频地址</span>(.*?)/span>', text, re.S)[0]
url_video = re.findall('<span class="leleplayer-info-panel-item-data">(.*?)<', url_data)[0]
browser.quit()
video_content = requests.get(url=url_video).content
with open('C:\\Users\\咕噜咕噜哟\\Desktop\\视频动漫\\' + name +  '.mp4', mode="wb") as video:
            video.write(video_content)

三. 完整代码如下(代码粗糙,望谅解)

1.执行文件:爬虫.py

import os
import re
import time
import checkOutTime
from crawBySelenium import selum

#存取原网页地址
url_list = [
]
# 起始集到结束集
episode_list = [
]

for j in range(0, len(url_list)):
    response = checkOutTime.getHtml(url_list[j])
    time.sleep(1)
    # print(response.text)
    name = re.findall('<h1 class="title text-fff">(.*?)</h1>', response.text)[0]
    name = name.replace(' ', '_')
    print('-----------------------------')
    print(name)
    print('-----------开始下载-----------')
    if os.path.exists('C:\\Users\\咕噜咕噜哟\\Desktop\\视频动漫\\' + name):
        print("文件已经存在")
    else:
        os.makedirs('C:\\Users\\咕噜咕噜哟\\Desktop\\视频动漫\\' + name)
    url = url_list[j][:-5] + '-1-'
    episode = episode_list[j].split('-')
    episode_start = episode[0]
    episode_end = episode[1]
    for i in range(int(episode_start), int(episode_end) + 1):
        start_time = time.time()
        i = str(i)
        play_url = url + i + ".html"
        # print(play_url)
        play_url1 = play_url.replace('vodetail', 'vodplay')
        # print(play_url1)
        new_response = checkOutTime.getHtml(play_url1)
        time.sleep(1)
        # print(new_response.text)
        title = re.findall('<small class="text-red">(.*?)</small>', new_response.text)[0]
        print(name + '  ' + title + '  正在下载......')
        m3u8 = re.findall('"link_next":".*?","url":"(.*?)",', new_response.text)[0]
        m3u8_url = "https://danmu.yhdmjx.com/m3u8.php?url=" + m3u8
        # print(m3u8_url)
        selum.selCraw(name, title, m3u8_url, start_time)

2.获得视频url并保存文件:selum.py

import re
import time

from selenium import webdriver
from selenium.webdriver import ActionChains
from tqdm import tqdm

import checkOutTime



def selCraw(name, title, url, start_time):
    browser = webdriver.Chrome()
    browser.get(url)
    time.sleep(3)
    action = ActionChains(browser)
    try:
        e = browser.find_element('xpath', '//*[@id="lelevideo"]')
    except:
        print('错误')

    action.move_to_element(e).perform()
    action.context_click(e).perform()
    e = browser.find_element('xpath', '//*[@id="player"]/div[9]/div[1]/a')
    action.click(e).perform()
    text = browser.page_source
    # print(text)
    kind_data = re.findall('视频类型</span>(.*?)/span>', text, re.S)[0]
    kind = re.findall('<span class="leleplayer-info-panel-item-data">(.*?)<', kind_data)[0]
    # print('kind:'+kind)
    url_data = re.findall('视频地址</span>(.*?)/span>', text, re.S)[0]
    url_video = re.findall('<span class="leleplayer-info-panel-item-data">(.*?)<', url_data)[0]
    # print(url_video)
    browser.quit()

    if kind == 'normal':
        video_content = checkOutTime.getData(url_video, name, title).content
        time.sleep(1)
        with open('C:\\Users\\xxxx\\Desktop\\视频动漫\\' + name + '\\' + title + '.mp4', mode="wb") as video:
            video.write(video_content)
        end_time = time.time()
        time_c = end_time - start_time
        print('视频下载完成!!!   下载所用时间:' + str(time_c))

    else:
        m3u8_data = checkOutTime.getData(url_video, name, title).text
        time.sleep(1)
        # sub替换 提取需要的
        m3u8_data = re.sub('#EXT.*', ' ', m3u8_data).split()
        for ts in tqdm(m3u8_data):
            # print(ts)
            ts_url = checkOutTime.getFinalUrl(url_video) + ts
            # print(ts_url)
            ts_content = checkOutTime.getData(ts_url, name, title).content
            # print("请求数据成功")
            with open('C:\\Users\\xxxx\\Desktop\\视频动漫\\' + name + '\\' + title + '.mp4', mode="ab") as video:
                # print("传入中。。。")
                video.write(ts_content)
        end_time = time.time()
        time_c = end_time - start_time
        print('视频下载完成!!!   下载所用时间:' + str(time_c))
    time.sleep(2)

3.requets 获得网页源代码函数:checkOutTime.py

import requests

def getData(url, name, title):
    headers = {
        'User-Agent': 'xxx'
    }
    i = 0
    while i < 5:
        try:
            ts_data = requests.get(url=url, headers=headers, timeout=5)
            return ts_data
        except requests.exceptions.RequestException:
            i += 1


def getHtml(url):
    headers = {
        'Cookie': 'xxxxx',
        'User-Agent': 'xxxxx'
    }
    i = 0
    while i < 5:
        try:
            ts_data = requests.get(url=url, headers=headers, timeout=5)
            return ts_data
        except requests.exceptions.RequestException:
            i += 1

def getData1(url):
    headers = {
        'User-Agent': 'xxx'
    }
    i = 0
    while i < 5:
        try:
            ts_data = requests.get(url=url, headers=headers, timeout=5)
            return ts_data
        except requests.exceptions.RequestException:
            i += 1


# hls类型  m3u8视频类型的每个片段的url
def getFinalUrl(url):
    url_list = url.split('/')
    temp = url_list[2]
    length = len(url_list)
    rep = url_list[length - 1]
    if temp == 'omts.tc.qq.com' or temp == 'qycache.hs-mould.cn':
        url = url.replace(rep, '')
        # print(url)
        return url
    elif temp == 'play4.cp21.ott.cibntv.net':
        return ''

都看到这里了,觉得有用就留下你宝贵的赞吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LLGululu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值