忧伤_ 发表于 2020-2-16 17:11

爬虫练习传智一键下载

本帖最后由 忧伤_ 于 2020-2-16 17:21 编辑

**【起因】**
我们有门专业课的作业就是观看传智播客上的视频,但在它那个网站观看视频体验极差,不能快进之类的,因为视频的src是在F12中直接可见的,当时就直接复制链接放到IDM下载,但还要手动打名字,一两个视频还好,多了就有点烦(因为最后也没怎么看),当时就想要是能自动一键下载多好,刚好最近学了一点python,了解一些简单的爬虫,发现可以用爬虫可以实现我当初的想法,src可见 只是一个简单的爬虫 做下笔记跟大家分享一下 还请多多指教
**【找Url】**

我们需要获取每一个章节对应的url,先找一下他们的不同,点了几个链接发现不同的章节detail后面跟的字符不一样


返回主页面 F12 打开Network

按下一页 发现xhr下多了一个文件 应该是一些Ajax技术(我是看了一些资料才知道可以这样找的,挺管用的)

点进去可以找到区分不同章节的id数据

在headers找到url

**【代码部分】**
一开始用request.get()我是没加请求头的,看不到内容,用浏览器打开可以看到数据,就直接把浏览器里请求头复制过去了,刚开始是没问题都,第二天就报错了,发现是cookies问题 获取cookies搞了一早上 后面再写一下了
导入的包
```
import urllib
import requests
import time
import json
from urllib.request import urlretrieve# 视频下载的包
```

```
      def get_html(url):
            response = requests.get(url=url, headers=hd)
            if response.status_code == 200:
                print('已连接')
                return response.text
```
```
      now_time = int(time.time() * 1000)
      # 获取id的url
      page_url = f'http://stu.ityxb.com/back/bxg/preview/list?name=&isEnd=&pageNumber=1&pageSize=20&type=1&courseId=52aed3802e6e40cca38a21935254906c&t={now_time}'
      data = get_html(page_url)
      # 拿到了每一章的id 可用http://stu.ityxb.com/preview/detail/ +id 将进入特定章节
      data = json.loads(data)# 字符串转string 用load()不行
      if data['resultObject'] == 'needLogin':
            print('cookie已失效,请更换')
      else:
            data = data['resultObject']['items'] #包含id的一个列表
```
```
            # 需求 输入name 返回id
               def get_id():# 英文的括号打在这里看不见是为什么啊
                      count = input('请按序号输入你要查看的章节:')
                     return data[-counts]['id']

```
再写这个函数的时候发现基础有多么重要{:1_908:} 列表是倒序的 可用负数的下标 一开始折腾了好久

下面就是对每一章的数据做一个获取,对get请求回来的一个数据筛选

```
                chapter_id = get_id()
                # 发现更好的url
                chapter_url = f'http://stu.ityxb.com/back/bxg/preview/info?previewId={chapter_id}&t=1581508416923'
                # 获取到章节里得页面 get_html会返回text
                chapter_page = get_html(chapter_url)
                # 字符串转json
                chapter_data = json.loads(chapter_page)
                chapter_num = chapter_data['resultObject']['preview']['previewName']
                chapter_data = chapter_data['resultObject']['chapters']# ['points']
                title = chapter_data['chapter']['point_name']
                title = f'{chapter_num}\t{title}'# 找标题
                content = chapter_data['points']# 特定章节中所有的数据 有视频名称和链接 是一个列表
                print(f'\t\t\t{title}')

```
下面对视频数据的一个遍历 并将 名称和链接放到一个新的列表中 方便使用
```
                              gather = []
                for content_index in content:
                  # 用列表存起来
                  name = content_index['point_name']
                  video_url = content_index['video_url']
                  a = {
                        'name': name,
                        'video': video_url
                  }
                  gather.append(a)
```
下载视频代码
```
            menu = (input('你要从第几节下载(将从该节开始自动往后下载)'))
            path = input('请输入下载路径:(请确保文件夹存在 防止出错)')
            for download_index in range(menus - 1, len(gather)):
                h = download_index + 1                                                      
                names = gather['name']
                v_url = gather['video']
                file_name = f'{h}.{names}'
                urlretrieve(v_url, r'{}\{}.mp4'.format(path, file_name)) # 下载函数
```

**【模拟登录】**
主要代码就在上面了,还有一个就是开始提到的cookies问题 在程序报错后我就上网站复制了新的cookies过来 程序可以运行 然后就去百度怎么获取cookies找了蛮久的(一个小坑:获取到的cookies跟网站看到的不一样,但都可以用。)
```
    user = input('请输入你的用户名:')
    psw = input('请输入你的密码:')
    url_ = 'http://stu.ityxb.com/back/bxg_anon/login'# 这里可以验证用户名密码
    from_data = {
      'automaticLogon': 'false',
      'username': user,
      'password': psw
    }
      #get 和 post都可以发送数据 不同的是post 用 data get 用params
    response = requests.post(url_, data=from_data)
    cookies = requests.utils.dict_from_cookiejar(response.cookies)
    #获取到的cookies是字典格式的 用户名或密码错误的获得的cookies是一个空字典,所以可以有一个判断
    if cookies:
      js_id = cookies['JSESSIONID']
      uc_t = cookies['_uc_t_']
      print('成功登录')
      new_url = 'http://stu.ityxb.com/back/bxg/preview/list?name=&isEnd=&pageNumber=1&pageSize=20&type=1&courseId=52aed3802e6e40cca38a21935254906c&t=1581574348194'
      new_cookies = f'JSESSIONID={js_id}; _uc_t_={uc_t};'
      hd = {
            'Accept': 'application/json, text/plain, */*',
            'Accept-Encoding': 'gzip, deflate',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Connection': 'keep-alive',
            'Cookie': new_cookies,
            'Host': 'stu.ityxb.com',
            'Referer': 'http://stu.ityxb.com/learning/52aed3802e6e40cca38a21935254906c/preview/list',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                        'Chrome/78.0.3904.70 Safari/537.36 '
      }
    else:
      print('用户名或密码错误')

```
下载效果:

上面的代码里我删除了一些可有无的代码,主要是为了代码尽可能的简洁 第一次发帖 文中不当之处还请多多指正{:1_893:} 打完了不小心删了一部分 心态崩了

忧伤_ 发表于 2020-2-17 16:01

stefaniema 发表于 2020-2-17 14:23
很好的练手爬虫,谢谢

确实,都把数据打包好了{:1_886:}他们网站有个视频资源栏目也跟这个差不多,有兴趣的话可以试下手:lol

忧伤_ 发表于 2020-2-16 17:23

最后一张不知道怎么放那里了{:1_896:}

s466692282 发表于 2020-2-16 21:07

学习了!!

忧伤_ 发表于 2020-2-16 21:52

s466692282 发表于 2020-2-16 21:07
学习了!!

哈哈哈,虽然改bug的时间比手动下载的时间多得多,但那自动下载的感觉真的很爽:lol

Norton 发表于 2020-2-16 22:57

楼主给力,多谢分享。

TomRoosevelt 发表于 2020-2-17 06:46

谢谢分享

w92vv 发表于 2020-2-17 08:21

多谢分享 学习了!{:1_921:}

laohu2277 发表于 2020-2-17 10:23

非常感谢

stefaniema 发表于 2020-2-17 14:23

很好的练手爬虫,谢谢
页: [1] 2 3
查看完整版本: 爬虫练习传智一键下载