Python爬虫(三)–Coursera抓站小结 Home » 编程开发 » Python爬虫(三)–Coursera抓站小结 系统:Mac OS X 10.10.1编辑器: Sublime Text2Python版本: 2.7.8模块依赖: import sys, string, re, random, urllib, urllib2, cookielib, getpass(均为系统内的模块) 0. 抓站小结0.1. cookie处理 需要进行登陆的时候, 要进行cookie的处理,使用以下方法 12345 cookie = cookielib.CookieJar()opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))urllib2.install_opener(opener)req = urllib2.Request(url)content = urllib2.urlopen(req) 0.2. 表单处理 某些网站需要进行账户和密码登陆, 需要使用POST方法向服务器发送账户和密码表单数据, 这里就需要模拟登陆. 如何获取表单数据的格式呢? 通过谷歌浏览器开发者工具中Network锁定请求头部和post发出的表单数据,伪装表单数据 当由于Method太多, 找不到POST提交登录请求Method方法的时候, 可以尝试使用错误密码, 这样就可以容易的找POST方法对应的头部. 12345 form_data = urllib.urlencode({ #注意urlencode方法 "email": self.user_name, "password": self.password, "webrequest": "true"}) 0.3. 防盗链和伪装成浏览器访问 防盗链就是需要在请求的头部加入Referer字段, Referer 指的是HTTP头部的一个字段, 用来表示从哪儿链接到目前的网页,采用的格式是URL。换句话说,借着 HTTP Referer 头部网页可以检查访客从哪里而来,这也常被用来对付伪造的跨网站请求。 伪装成浏览器就是将User-Agent设置为浏览器的字段 1234567 user_agent = ("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/38.0.2125.111 Safari/537.36")request_header = { "Referer": "https://accounts.coursera.org/signin", #对付防盗链设置, 为跳转来源的url "User-Agent": user_agent, #伪装成浏览器访问} 1. 伪装头部 使用谷歌浏览器自带的开发者工具, 选择Network(Element用来查看网站源码等功能), 获取详细的GET和POST方法, 从中获取登录请求的的头部信息,从POST中获得Headers信息如下(省略部分不重要信息) 12345678910111213141516171819202122 Request URL:https://accounts.coursera.org/api/v1/login //真正的登陆验证页面Request Method:POSTStatus Code:401 Unauthorized//Request HeadersConnection:keep-aliveContent-Length:55Content-Type:application/x-www-form-urlencodedCookie:(省略cookie信息, 下面详细介绍)...Referer:https://accounts.coursera.org/signin //防盗链设置User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 //浏览器浏览标识//下面四行为服务器所做的限制字段X-CSRF2-Cookie:csrf2_token_el67QDLgX-CSRF2-Token:1oxZDVMuZGX0qCggdReQyj2RX-CSRFToken:WnVtiMDpvw0JXJqHjPrFk0EUX-Requested-With:XMLHttpRequest//Form Dataemail:1095...@qq.com //Coursera账户信息 password:FAFA //账户密码webrequest:true //固定字段 这样就能写出模拟头部的函数 123456789101112131415 def structure_headers(self) : #模拟表单数据,这个参数不是字典 form_data = urllib.urlencode({ "email": self.user_name, "password": self.password, "webrequest": "true" }) user_agent = ("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/38.0.2125.111 Safari/537.36") request_header = { "Referer": "https://accounts.coursera.org/signin", #对付防盗链设置, 为跳转来源的url "User-Agent": user_agent, #伪装成浏览器访问 } return form_data, request_header 试了几次竟然都是400错误, 也就是头部请求的格式不正确, 通过多次Headers查看, 发现有下面四处不同的头部 1234 X-CSRF2-Cookie:csrf2_token_hTu4Zy8Y 最后八位不同X-CSRF2-Token:O5OIRan9I99lTHmnYS27ocYb 完全随机X-CSRFToken:HClYbs9HZoGweU54iR5r5z2y 完全随机X-Requested-With:XMLHttpRequest 固定不变 通过放上搜索找到了解决方案, coursera的请求头部中X-CSRF2-Token和X-CSRFToken是完全随机的, X-CSRF2-Cookie后八位是随机生成的, 都是由字母和数字随机生成的. 于是修改代码如下: 12345678910111213141516171819202122232425262728 def structure_headers(self) : #模拟表单数据,这个参数不是字典 form_data = urllib.urlencode({ "email": self.user_name, "password": self.password, "webrequest": "true" }) user_agent = ("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/38.0.2125.111 Safari/537.36") XCSRF2Cookie = 'csrf2_token_%s' % ''.join(self.random_string(8)) XCSRF2Token = ''.join(self.random_string(24)) XCSRFToken = ''.join(self.random_string(24)) cookie = "csrftoken=%s; %s=%s" % (XCSRFToken, XCSRF2Cookie, XCSRF2Token) request_header = { "Referer": "https://accounts.coursera.org/signin", #对付防盗链设置, 为跳转来源的url "User-Agent": user_agent, #伪装成浏览器访问 "X-Requested-With": "XMLHttpRequest", "X-CSRF2-Cookie": XCSRF2Cookie, "X-CSRF2-Token": XCSRF2Token, "X-CSRFToken": XCSRFToken, "Cookie": cookie } return form_data, request_headerdef random_string(self, length): return ''.join(random.choice(string.letters + string.digits) for i in xrange(length)) 2. 模拟登陆 登陆coursra的下载页面时计算机组成视频下载, 会发现是要求登陆呢, 这时候就使用cookielib模块进行cookie的处理 123456789101112131415161718 def simulation_login(self) : cookie = cookielib.CookieJar() opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie)) urllib2.install_opener(opener) form_data, request_header = self.structure_headers() req = urllib2.Request(self.login_url, data = form_data, headers = request_header) try : result = urllib2.urlopen(req) except urllib2.URLError,e : if hasattr(e, "code"): print "The server couldn't fulfill the request.Please check your url and read the Reason" print "Error code: %s" % e.code elif hasattr(e, "reason"): print "We failed to reach a server. Please check your url and read the Reason" print "Reason: %s" % e.reason sys.exit(2) if result.getcode() == 200 : print "登陆成功..." 这个函数用于模拟登陆, 并显示登陆成功或者失败 3. 抓取下载链接 抓取链接通过正则表达式, 主要匹配PDF下载链接和MP4视频下载链接 使用re.findall()函数进行函数匹配 1234567891011121314151617