使用Python模拟腾讯第三方认证-篇4 [自动爬取分析及下载]

距离上次发布已经过去2个月之多,最近总结的时间越来越少,只能挤着来总结了。终于花了点时间将页面分析与下载工作完成。

工程准备

既然是自动爬取,尽量使用Scrapy框架,Scrapy的安装和使用请自行查询和学习。
对于HTML解析,推荐使用BeautifulSoup, 查询定位页面元素很方便。
使用Scrapy创建一个新的工程。
scrapy startproject jiekespider得到工程目录如下:

|--- scrapy.cfg
|    |--- jiekespider
|    |    |--- __init__.py
|    |    |--- items.py
|    |    |--- pipelines.py
|    |    |--- settings.py
|    |    |--- spiders
|    |    |    |---- __init__.py
|    |    |    |---- jiekespider.py # 手动创建此爬虫文件

然后需要更改两个文件,setting.py和items.py

setting.py

找到ITEM_PIPELINES,然后添加文件流水包处理,启用文件保存功能:

# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'scrapy.contrib.pipeline.file.FilesPipeline': 1,
}

在最后添加文件存储位置:

FILES_STORE = "/home/bb/jike/"

item.py

Scrapy框架中item定义了要处理的页面的数据结构,比如学院课程信息包含:视频地址,课程名称,课程时长等:
添加LessonInfo类:

class LessonInfo(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    lesson = scrapy.Field()
    unit = scrapy.Field()
    time = scrapy.Field()
    file_urls = scrapy.Field()
    files = scrapy.Field()

然后是关键文件,jikespider.py:

#!python
# coding=utf-8

# import the necessary packages
from jikespider.items import *
import scrapy

from bs4 import BeautifulSoup

class JikeSpider(scrapy.Spider):
    name = "jike-spider"
    start_urls = ["http://www.jikexueyuan.com"]
    dest_url = "http://ke.jikexueyuan.com/zhiye/ios/"
    logined = 0

    #继承与父类,默认会调用的回应处理
    def parse(self, response):
        if self.logined == 0:
            #登陆处理
        else:
            #处理主页面
            yield scrapy.Request(self.dst_url, self.parse_main)

如果单纯学习分析网页自动解析下载这部分功能足够了,使用这套框架只会把某一课程的第一节下载下来,因为不需要登陆验证。

登陆处理模块没有在此列出,但是前面章节已经做过演示及关键代码的展示,后续整理好后将放到Github上分享。

页面分析

入口页面

我们开始分析,首先确认页面入口,比如我使用了职业课程页面, 职业课程页面中选择IOS为启动URL,地址为:
http://ke.jikexueyuan.com/zhiye/ios/

Screenshot from 2016-01-25 13:03:19.png

查看源码可以看到从初级到高级的课程地址都分别在lesson-unit下,其中我们关心的时实际课程的URL,例如:

 <a jktag="0001|0.1|93004|acid:1225|levelid:19|stageid:49|slug:ios" target="_blank" href="http://www.jikexueyuan.com/course/1225.html" title="iOS 开发的前世今生" class="inner"> <span>1.iOS 开发的前世今生</span> <em class="tag"> </em> <i class="learn-state"></i> </a>

查看href项为http://www.jikexueyuan.com/course/1225.html,class为inner,则可将整个页面的课程URL查找出来:

def parse_main(self, response):
    soup = BeautifulSoup(response.body, "lxml")
    links = soup.find_all('a', class_="inner")

    #遍历课程,转向下级分析
    for link in links:
        l = link['href']
        yield scrapy.Request(l,    self.parse_sub)

课程页面

现在可以进行分析课程页面http://www.jikexueyuan.com/course/1225.html, 查看源码,可以分析出以下关键信息:

  • 课程名称
  • 子章节名称,课时及URL
    子课程URL规律:
    学院的单个课程的URL与第一个子章节的URL很像,例如http://www.jikexueyuan.com/course/1225.html,第一章URL为http://www.jikexueyuan.com/course/1225_1.html?ss=1,第2章URL为http://www.jikexueyuan.com/course/1225_2.html?ss=1。所以可以考虑自己构建URL进行请求。
    另外,分析可以看到子章节是在<div class='text-box'>块内,在一个text-box中会有课时的URL:
                                <div class="text-box">
                                    <h2>
                                        <a href="http://www.jikexueyuan.com/course/616_1.html?ss=1" jktag="&posArea=0007&posAOper=8035&posColumn=2877.1"> 课程介绍</a>

                                        <p class="f_r">00:34</p>
                                    </h2>
                                    <p>本课时对课程内容做一简要介绍。</p>
                                </div>

那么子章节的URL就都可以从text-box中取出, 然后交给后面处理:

def parse_sub(self, response):
    soup = BeautifulSoup(response.body, "lxml")
    lesson_box = soup.find_all('div', class_='text-box')

    for l in lesson_box:
        sub_l = l.h2.a['href']
        yield scrapy.Request(sub_l,    self.parse_sub_info)

子章节页面

子章节页面类似这样的http://www.jikexueyuan.com/course/1225_1.html?ss=1地址,到来关键的课程页面,重申以下,至此我们想要的视频才算是能解析了。
学院使用了video-js控件,并且支持HTML5的页面是包含source节点,这里浏览器看不到source节点就算了,还是抓取分析。
整个子课程页面只使用一个播放器,故我们只关心source节点。
另外课子章节名称和时长在text-box块内,课程名在lesson-teacher块内。

def parse_sub_info(self, response):
    f_r = "00:00"
    lesson = ""
    unit = ""
    file_urls = ""
    id = ""
    soup = BeautifulSoup(response.body, "lxml")

    #查找子课程信息:时长和名称
    lesson_box = soup.find_all('div', class_='text-box')
    for l in lesson_box:
        sub_l = l.h2.a['href']
        print sub_l
        if (response.url == sub_l):  #因为多做了一次请求,只处理与本URL一致的课程信息
            unit = l.h2.a.string
            f_r = l.p.string
            break

    #查找课程视频地址
    source = soup.find_all('source')
    if len(source):
        print source[0]['src']
        file_urls = source[0]['src']
    #查找课程名称
    lesson_teacher = soup.find_all('div', class_='lesson-teacher')
    if len(lesson_teacher) == 1:
        lesson = lesson_teacher[0].div.h2.string
        print lesson

    #子课程名添加编号,方便按顺序查看
    id = re.findall("\_(.*)\.html", response.url)
    if len(id):
        unit = id[0] + unit

    #将课程信息推送到LessonInfo 处理单元(Item),后续保存和下载由Scapy自动完成
    if len(file_urls) and len(lesson):
        # yield the result
        yield LessonInfo(lesson=lesson, unit=unit, time=f_r, file_urls=[file_urls])

运行测试

使用scrapy crawl jike-spider -o video.json即将jike-spider初始化运行,-o为制定输出结果文件。
运行后Scrapy会将整个IOS课程子章节分别下载到设定的目录中,并且在当前目录生成抓取结果文件video.json。
如下内容:

[{"files": [{"url": "http://cv4.jikexueyuan.com/a561bd397474a8449303864d26cfd96b/201601221755/ios/course_1225/01/video/c1225b_01_h264_sd_960_540.mp4", "path": "full/f165d19a878d1048df08f6cc9ba389ee1480bcf6.mp4", "checksum": "357b934b62b2f564bdfff1628f5b180c"}], "lesson": "iOS \u5f00\u53d1\u7684\u524d\u4e16\u4eca\u751f", "unit": "1 iOS \u5f00\u53d1\u7684\u524d\u4e16\u4eca\u751f", "file_urls": ["http://cv4.jikexueyuan.com/a561bd397474a8449303864d26cfd96b/201601221755/ios/course_1225/01/video/c1225b_01_h264_sd_960_540.mp4"], "time": "06:02"},
{"files": [{"url": "http://cv4.jikexueyuan.com/c9c10ce5ea141d5b0b347ef12b4bbf94/201601221755/course/1701-1800/1782/video/4830_b_h264_sd_960_540.mp4", "path": "full/3cfc51a0ec32349df5113d014fe2e64705af84e1.mp4", "checksum": "561e26ff5fe6e209726c077734fb4df0"}], "lesson": "\u5229\u7528 Map Kit \u521b\u5efa\u5730\u56fe\u5e76\u6dfb\u52a0\u81ea\u5b9a\u4e49\u6807\u8bc6", "unit": "1 Map Kit \u57fa\u7840\u8bb2\u89e3", "file_urls": ["http://cv4.jikexueyuan.com/c9c10ce5ea141d5b0b347ef12b4bbf94/201601221755/course/1701-1800/1782/video/4830_b_h264_sd_960_540.mp4"], "time": "04:02"},
...

然后在设定的输出目录中可以看到文件在不断的下载,网速一般,可以喝杯咖啡了~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 序 前面两篇演示了模拟腾讯第三方认证的过程,至此已经能够自由登录学院网站。下面就要开始探索如何写一个简单的爬虫,分...
    LittleFat阅读 1,260评论 0 9
  • 在之前一篇抓取漫画图片的文章里,通过实现一个简单的Python程序,遍历所有漫画的url,对请求所返回的html源...
    msq3阅读 12,687评论 14 88
  • 这两天摸索了下scrapy,刚看文档的时候觉得有点生无可恋,scrapy框架个人还是觉得比较难懂的,需要学习的地方...
    Treehl阅读 5,623评论 7 10
  • 摘文:“每个人的心里,都有一种情感需要表达。我们需要一种方式,来描述内心的悸动。我们需要一种通道,来写出生命的美好...
    季秋简文阅读 346评论 0 2
  • 1. 前两天大姨妈来疼的厉害,想起之前看的那个视频,因为姨妈疼再加上熬夜得了卵巢癌,我有点担心自己。 去医院检查,...
    曲尚阅读 903评论 15 11