<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [繼豆瓣抓站后再對Coursera下手](http://www.jianshu.com/p/f76bd2164856) > 系統:Mac OS X 10.10.1 > 編輯器: Sublime Text2 > Python版本: 2.7.8 > 模塊依賴: import sys, string, re, random, urllib, urllib2, cookielib, getpass(`均為系統內的模塊`) * * * # 0\. 抓站小結 ## 0.1\. cookie處理 需要進行登陸的時候, 要進行cookie的處理,使用以下方法 ~~~ 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方法對應的頭部. ![找到POST方法](http://picturebag.qiniudn.com/Snip20141207_2.png) 找到POST方法 ![表單處理](http://picturebag.qiniudn.com/Snip20141207_3.png) 表單處理 ~~~ form_data = urllib.urlencode({ #注意urlencode方法 "email": self.user_name, "password": self.password, "webrequest": "true" }) ~~~ ## 0.3\. 防盜鏈和偽裝成瀏覽器訪問 防盜鏈就是需要在請求的頭部加入`Referer`字段, Referer 指的是HTTP頭部的一個字段, 用來表示從哪兒鏈接到目前的網頁,采用的格式是URL。換句話說,借著 HTTP Referer 頭部網頁可以檢查訪客從哪里而來,這也常被用來對付偽造的跨網站請求。 偽裝成瀏覽器就是將`User-Agent設置為瀏覽器的字段` ![偽裝頭部](http://picturebag.qiniudn.com/Snip20141207_5.png) 偽裝頭部 ~~~ 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信息如下(`省略部分不重要信息`) ~~~ Request URL:https://accounts.coursera.org/api/v1/login //真正的登陸驗證頁面 Request Method:POST Status Code:401 Unauthorized //Request Headers Connection:keep-alive Content-Length:55 Content-Type:application/x-www-form-urlencoded Cookie:(省略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_el67QDLg X-CSRF2-Token:1oxZDVMuZGX0qCggdReQyj2R X-CSRFToken:WnVtiMDpvw0JXJqHjPrFk0EU X-Requested-With:XMLHttpRequest //Form Data email:1095...@qq.com //Coursera賬戶信息 password:FAFA //賬戶密碼 webrequest:true //固定字段 ~~~ 這樣就能寫出模擬頭部的函數 ~~~ 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查看, 發現有下面四處不同的頭部 ~~~ 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`后八位是隨機生成的, 都是由字母和數字隨機生成的. 于是修改代碼如下: ~~~ 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_header def random_string(self, length): return ''.join(random.choice(string.letters + string.digits) for i in xrange(length)) ~~~ # 2\. 模擬登陸 登陸coursra的下載頁面時[計算機組成視頻下載](https://class.coursera.org/pkuco-001/lecture), 會發現是要求登陸呢, 這時候就使用`cookielib`模塊進行cookie的處理 ~~~ 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()`函數進行函數匹配 ~~~ def get_links(self) : try : result = urllib2.urlopen(self.url) except urllib2.URLError,e : if hasattr(e, "code"): print "The server couldn't fulfill the request." 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) content = result.read().decode("utf-8") print "讀取網頁成功..." down_links = re.findall(r'<a.*?href="(.*?mp4.*?)"', content) down_pdfs = re.findall(r'<a.*?href="(.*?pdf)"', content) print "正則匹配結束..." return down_links, down_pdfs ~~~ # 4\. 寫入完本 既然已經匹配了所有的鏈接, 這一步就是將鏈接寫入到文件中 ~~~ def start_spider(self) : self.simulation_login() down_links, down_pdfs = self.get_links() with open("coursera.html", "w+") as my_file : print "下載鏈接的長度", len(down_links) for link in down_links : print link try : my_file.write(link + "\n") except UnicodeEncodeError: sys.exit(2) with open("coursera.pdf", "w+") as my_file : print "下載pdf的長度", len(down_pdfs) for pdf in down_pdfs : try : my_file.write(pdf + "\n") except UnicodeEncodeError : sys.exit(2) print "抓取Coursera課程下載鏈接和pdf鏈接成功" ~~~ # 5\. 登陸調用 使用`getpass模塊中的getpass()`輸入密碼, 使用這個函數輸入密碼的時候不會顯示任何字符, 貌似體驗不好, 下次修改一下, 然后命令行傳入下載課程的參數. 通過比較每門課下載頁面, 發現之后`/lecture`前的這個字段是不同的,這樣可以設置通過命令行傳入這這個參數 [https://class.coursera.org/pkuco-001/lecture](https://class.coursera.org/pkuco-001/lecture) [https://class.coursera.org/electromagnetism-001/lecture](https://class.coursera.org/electromagnetism-001/lecture) > 這里在運行命令行只需要傳入`pkuco-001或者electromagnetism-001`這種字段 ~~~ def main() : if len(sys.argv) != 2 : print "Please Input what course you want to download.." sys.exit(2) url = "https://class.coursera.org/{course}/lecture" user_name = raw_input("Input your Email > ") password = getpass.getpass("Input your Password > ") spider = Coursera(url.format(course = sys.argv[1]), user_name, password) spider.start_spider() ~~~ # 6\. 下載腳本 下載可以使用`curl`, Mac下安裝方法 ~~~ brew install curl ~~~ 編寫下載使用的Python腳本, 編寫成功后, 修改腳本文件的文件權限 ~~~ chmod 755 downloadshell.py #最后一個參數為Python腳本名稱 ~~~ 運行下載腳本 ~~~ $python downloadshell.py coursera.pdf #最后一個參數為連接保存文件 ~~~ 下面是我自己編寫的簡單的下載腳本 ~~~ #!/usr/bin/python2 # -*- coding:utf-8 -*- #簡單的文件下載腳本 import os import sys, re def read_file(file_name) : down_links = [] with open(file_name, "r") as my_file : for url in my_file : down_links.append(url.replace("\n", "")) return down_links def main() : if len(sys.argv) != 2 : print "Please input file name..." sys.exit(2) down_links = read_file(sys.argv[1]) pdf_index = 1 mp4_index = 1 for index, link in enumerate(down_links) : if link.find("mp4") != -1 : os.system("curl " + link + " -o " + "%d.mp4" % mp4_index) elif link.find("pdf") != -1 : os.system("curl " + link + " -o " + "%d.pdf" % pdf_index) pdf_index += 1 else : print "請自行補全下載命令..." if __name__ == '__main__': main() ~~~ # 7.完整代碼查看 [Github完整代碼](https://github.com/Andrew-liu/coursera_spider)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看