网站调用新浪微博内容(Coursera去一个文件的下载,只有傻子才那么干! )

优采云 发布时间: 2022-01-19 18:08

  网站调用新浪微博内容(Coursera去一个文件的下载,只有傻子才那么干!

)

  首先按照文章的思路,自己试了一下,可以成功

  有时候我们需要采集一些经典的东西,时不时回味一下,Coursera上的一些课程无疑是经典。Coursera中完成的大部分课程都提供了完整的配套教学资源,包括ppt、视频和字幕等,离线后学习起来非常容易。很明显,我们不是逐个文件下载的,只有傻子才会这样做,程序员是聪明人!

  那么我们聪明的人会怎么做呢?当然,写个脚本批量下载。首先我们需要分析一下手动下载的过程:登录我们的Coursera账号(有些课程需要我们登录并选择一门课程才能看到对应的资源),在课程资源页面找到对应的文件链接,然后使用喜欢的工具下载。

  很简单,对吧?我们可以用程序来模仿上面的步骤,这样我们就可以解放双手了。整个程序可以分为三个部分:

  登录 Coursera;在课程资源页面上找到资源链接;根据资源链接选择合适的工具下载资源。

  让我们详细实现以下内容!

  登录

  一开始没有加登录模块,以为访问者可以下载相应的课程资源。后来在测试comnetworks-002课程时,发现访问者在访问资源页面时会自动跳转到登录界面。下图显示chrome是隐身的。访问本课程的资源页面时的模式。

  

  模拟登录,我们先找到登录页面,然后使用谷歌的开发者工具分析账号密码是如何上传到服务器的。

  我们在登录页面的表格中填写账号密码,然后点击登录。同时,我们需要关注Developer Tools-Network,找到提交账号信息的url。一般情况下,如果要向服务器提交信息,一般采用post方式。这里我们只需要先找到 Method 为 post 的 url。可悲的是,每次登录我的账户,提交账户信息的地址在网络中都找不到。猜到登录成功后,直接跳转到登录成功后的页面,你要找的内容一闪而过。

  于是我只输入了一组账号密码,故意登录失败。果然找到了帖子的页面地址,如下图:

  

  地址是: 。为了知道已经向服务器提交了哪些内容,进一步观察post页面中表单的内容,如下图:

  

  我们看到总共有三个字段:

  接下来,我们来写吧。我选择使用python的Requests库来模拟登录。这是Requests官网介绍的。

  Requests 是一个优雅而简单的 Python HTTP 库,专为人类构建。

  其实request使用起来真的很简单方便,这要归功于专门为人类设计的http库。requests 提供了一个 Session 对象,可以用来在不同的请求中传递一些相同的数据,比如在每个请求中携带 cookie。

  初步代码如下:

  signin_url = "https://accounts.coursera.org/api/v1/login"

logininfo = {"email": "...",

"password": "...",

"webrequest": "true"

}

user_agent = ("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) "

"AppleWebKit/537.36 (KHTML, like Gecko) "

"Chrome/36.0.1985.143 Safari/537.36")

post_headers = {"User-Agent": user_agent,

"Referer": "https://accounts.coursera.org/signin"

}

coursera_session = requests.Session()

login_res = coursera_session.post(signin_url,

data=logininfo,

headers=post_headers,

)

if login_res.status_code == 200:

print "Login Successfully!"

else:

print login_res.text

  将表单中提交的内容存储在字典中,然后作为数据参数传递给 Session.post 函数。一般情况下最好加上User-Agent、Referer等请求头,User-Agent用来模拟浏览器请求,Referer用来告诉服务器我是从referer页面跳转到请求的页。有时服务器会检查请求的Referer字段,以确保当前请求页面是从固定地址跳转的。

  运行上述代码段的结果很奇怪,显示以下消息:Invalid CSRF Token。后来在github上搜索了一个Coursera的批量下载脚本,发现当人们发送页面请求时,headers多了四个字段:XCSRF2Cookie、XCSRF2Token、XCSRFToken、cookie。于是又查看了post页面的请求头,发现确实有这些字段,估计是服务端用来做一些限制的。

  用浏览器登录几次后发现XCSRF2Token,XCSRFToken是一个长度为24的随机字符串,而XCSRF2Cookie是“csrf2_token_”加上一个长度为8的随机字符串。但是一直没弄清楚cookie是怎么获取的,但是查看github上的代码,cookie似乎只是“csrftoken”和其他三个的组合。我试过了,它奏效了。

  将以下部分添加到原创代码中就足够了。

  def randomString(length):

return ''.join(random.choice(string.letters + string.digits) for i in xrange(length))

XCSRF2Cookie = 'csrf2_token_%s' % ''.join(randomString(8))

XCSRF2Token = ''.join(randomString(24))

XCSRFToken = ''.join(randomString(24))

cookie = "csrftoken=%s; %s=%s" % (XCSRFToken, XCSRF2Cookie, XCSRF2Token)

post_headers = {"User-Agent": user_agent,

"Referer": "https://accounts.coursera.org/signin",

"X-Requested-With": "XMLHttpRequest",

"X-CSRF2-Cookie": XCSRF2Cookie,

"X-CSRF2-Token": XCSRF2Token,

"X-CSRFToken": XCSRFToken,

"Cookie": cookie

}

  至此,登录功能已经初步实现。

  分析资源链接

  登录成功后,我们只需要获取资源页面的内容,然后过滤掉我们需要的资源链接即可。资源页面的地址很简单,name就是课程名称。例如,对于课程 comnetworks-002,资源页面地址为 .

  抓取到页面资源后,我们需要分析html文件,这里我们选择使用BeautifulSoup。BeautifulSoup 是一个强大的 Python 库,可以从 HTML 或 XML 文件中提取数据。具体使用官网有非常详细的文档,这里不再赘述。在使用 BeautifulSoup 之前,我们必须找出资源链接的规律,以便进行过滤。

  课程每周总话题在class=course-item-list-header的div标签下,每周课程在class=course-item-list-section-list的ul标签下,每门课程是在 li 标签下,课程资源位于 li 标签中的 div 标签中。

  看了几门课程,发现过滤资源链接的方法很简单,如下:

  ppt和ppt资源:使用正则表达式匹配链接;字幕资源:找到title="Subtitles (srt)" 的标签,取其href属性;视频资源:找到 title="Video (MP4)" 的标签,取其 href 属性。

  字幕和视频也可以使用正则表达式进行过滤,但使用 BeautifulSoup 根据标题属性进行匹配,以获得更好的可读性。但是ppt和pdf资源没有固定的title属性,所以必须使用正则表达式来匹配。

  具体代码如下:

  soup = BeautifulSoup(content)

chapter_list = soup.find_all("div", class_="course-item-list-header")

lecture_resource_list = soup.find_all("ul", class_="course-item-list-section-list")

ppt_pattern = re.compile(r'https://[^"]*\.ppt[x]?')

pdf_pattern = re.compile(r'https://[^"]*\.pdf')

for lecture_item, chapter_item in zip(lecture_resource_list, chapter_list):

# weekly title

chapter = chapter_item.h3.text.lstrip()

for lecture in lecture_item:

lecture_name = lecture.a.string.lstrip()

# get resource link

ppt_tag = lecture.find(href=ppt_pattern)

pdf_tag = lecture.find(href=pdf_pattern)

srt_tag = lecture.find(title="Subtitles (srt)")

mp4_tag = lecture.find(title="Video (MP4)")

print ppt_tag["href"], pdf_tag["href"]

print srt_tag["href"], mp4_tag["href"]

  下载资源

  既然已经获取了资源链接,下载部分就很容易了,这里我选择使用curl来下载。具体思路很简单,就是将curl resource_link -o file_name 输出到一个*敏*感*词*文件,比如feed.sh。这样,你只需要赋予torrent文件执行权限,然后运行torrent文件即可。

  为了方便对课程资源进行分类,可以为课程每周的标题创建一个文件夹,然后该周的所有课程都会下载到这个目录中。为了方便我们快速定位到每个类的所有资源,可以将一个类的所有资源文件命名为类名.文件类型。具体实现比较简单,这里不再给出具体方案。您可以查看测试示例中的 feed.sh 文件。部分内容如下:

  mkdir 'Week 1: Introduction, Protocols, and Layering'

cd 'Week 1: Introduction, Protocols, and Layering'

curl https://d396qusza40orc.cloudfront.net/comnetworks/lect/1-readings.pdf -o '1-1 Goals and Motivation (15:46).pdf'

curl https://class.coursera.org/comnetworks-002/lecture/subtitles?q=25_en&format=srt -o '1-1 Goals and Motivation (15:46).srt'

curl https://class.coursera.org/comnetworks-002/lecture/download.mp4?lecture_id=25 -o '1-1 Goals and Motivation (15:46).mp4'

curl https://d396qusza40orc.cloudfront.net/comnetworks/lect/1-readings.pdf -o '1-2 Uses of Networks (17:12).pdf'

curl https://class.coursera.org/comnetworks-002/lecture/subtitles?q=11_en&format=srt -o '1-2 Uses of Networks (17:12).srt'

curl https://class.coursera.org/comnetworks-002/lecture/download.mp4?lecture_id=11 -o '1-2 Uses of Networks (17:12).mp4'

  至此,我们已经成功完成爬取Coursera课程资源的目标,具体代码放在gist上。使用时,我们只需要运行程序,将课程名称作为参数传递给程序即可(这里的课程名称不是整个课程的全称,而是课程介绍页面地址中的缩写名称,如作为Computer Networks这个类,类名是comnetworks-002)。

  后来发现Coursera为我们提供了下载资源的接口。

  更新:2014 年 9 月 3 日

  其实这个程序可以看成是一个简单的爬虫小程序。下面简单介绍爬虫的概念。

  不是一个简单的爬虫

  关于什么是爬虫,这就是 wiki 所说的

  Web 爬虫是一种 Internet 机器人,它系统地浏览万维网,通常用于 Web 索引。

  爬虫整体架构如下(图片来自wiki):

  

  简单来说就是爬虫从Scheduler中获取初始url,下载对应的页面,存储有用的数据,同时分析页面中的链接。

  当然,有一些协议可以约束爬虫的行为。比如很多网站都有一个robots.txt文件来指定网站哪些内容可以爬取,哪些不能爬取。

  每个搜索引擎的背后都有一个强大的爬虫程序,它的触角延伸到网络的各个角落,不断采集有用的信息并建立索引。这种搜索引擎级别的爬虫实现起来非常复杂,因为互联网上的页面数量太多,仅仅遍历它们是非常困难的,更不用说分析页面信息和建立索引了。

  在实际应用中,我们只需要爬取特定站点,爬取少量资源,实现起来要简单得多。但是,仍然有很多令人头疼的问题。例如,许多页面元素是由 javascript 生成的。这时候,我们需要一个javascript引擎来渲染整个页面,然后进行过滤。

  雪上加霜的是,很多网站为了防止爬虫爬取资源采取了一些措施,比如在一段时间内限制对同一IP的访问次数,或者限制两次操作的时间间隔,添加验证码等等. 在大多数情况下,我们不知道如何在服务器端阻止爬虫,所以要让爬虫工作起来确实很困难。

  参考:

  github:coursera-dl/coursera

  github:coursera-下载器

  python抓取页面元素失败

  维基:网络爬虫

  如何开始使用 Python 爬虫?

  补充:上述过程中用到的python requests 模块的下载地址如下:

  requests模块文章的详细介绍如下:

  测试后完整代码如下:

  import requests

import random

import string

signin_url = "https://accounts.coursera.org/api/v1/login"

logininfo = {"email": "已注册邮箱",

"password": "密码",

"webrequest": "true"

}

user_agent = ("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)")

def randomString(length):

return ''.join(random.choice(string.letters + string.digits) for i in xrange(length))

XCSRF2Cookie = 'csrf2_token_%s' % ''.join(randomString(8))

XCSRF2Token = ''.join(randomString(24))

XCSRFToken = ''.join(randomString(24))

cookie = "csrftoken=%s; %s=%s" % (XCSRFToken, XCSRF2Cookie, XCSRF2Token)

post_headers = {"User-Agent": user_agent,

"Referer": "https://accounts.coursera.org/signin",

"X-Requested-With": "XMLHttpRequest",

"X-CSRF2-Cookie": XCSRF2Cookie,

"X-CSRF2-Token": XCSRF2Token,

"X-CSRFToken": XCSRFToken,

"Cookie": cookie

}

coursera_session = requests.Session()

login_res = coursera_session.post(signin_url,

data=logininfo,

headers=post_headers,

)

if login_res.status_code == 200:

print "Login Successfully!"

else:

print login_res.text

import re

import urllib

page = urllib.urlopen("https://class.coursera.org/comnetworks-002/lecture")

html = page.read()

print html,

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线