筆記之Python網絡數據採集

筆記之Python網絡數據採集

  • 非原創即採集
  • 一念清淨, 烈焰成池, 一念覺醒, 方登彼岸
  • 網絡數據採集, 無非就是寫一個自動化程序向網絡服務器請求數據, 再對數據進行解析, 提取須要的信息
  • 一般, 有api可用, api會比寫網絡爬蟲程序來獲取數據更加方便.

Part1 建立爬蟲

Chapter1 初建網絡爬蟲

  • 一旦你開始採集網絡數據, 就會感覺到瀏覽器爲咱們所作的全部細節, 它解釋了全部的html, css, JavaScript
  • 網絡瀏覽器是一個很是有用的應用, 它建立信息的數據包, 發送, 並把獲取的數據解釋成圖像, 聲音, 視頻, 或文字. 但網絡瀏覽器就是代碼, 而代碼是能夠分解的, 能夠分解成許多基本組件, 可重寫, 重用, 以及作成咱們想要的任何東西
  • 「域名爲kissg.me的服務器上<網絡應用根地址>/pages目錄下的html文件page1.html的源代碼"
  • 網絡瀏覽器與爬蟲程序的區別:
  • 瀏覽器遇到html標籤時, 會向服務器再發起對該資源的請求, 再用請求獲得的資源渲染頁面
  • 爬蟲程序並無返回向服務器請求多個文件的邏輯, 它只能讀取已經請求的單個html文件
  • BeautifulSoup經過定位html標籤來格式化和組織複雜的網絡信息, 以python對象展現xml結構信息
  • 先調用response.read()獲取網頁的內容, 再將html內容傳給BeautifulSoup對象, 造成的結構以下所示:
html <html><head>...</head><body>...</body></html> - head <head><title>A Useful Page<title></head> - title <title>A Useful Page</title> - body <body><h1>An Int...</h1><div>Lorem ip...</div></body> - h1 <h1>An Interesting Title</h1> - div <div>Lorem Ipsum dolor...</div> 
  • 所以能夠經過bsObj.html.body.h1的方式提取標籤
  • 請求的網頁在服務器上不存在時, 程序會返回http錯誤, urlopen函數會拋出HTTPError異常, 對此, 可以使用try ... except ...語句來處理
  • 服務器不存在, urlopen返回一個None對象, 可經過條件判斷簡單地處理
  • 當調用的標籤不存在時, BeautifulSoup會返回None對象, 請求None對象的子標籤, 會發生AttributeError錯誤, 一樣地, 也用try ... except ... 語句來處理
  • 一個良好的爬蟲程序首先要具有強大而周密的異常處理能力, 隨時應對網絡中可能存在的異常
  • 在寫爬蟲的時候, 思考代碼的整體格局, 讓代碼既能夠捕捉異常又容易閱讀, 很重要. 考慮代碼的重用性

Chapter2 複雜html解析

  • 當米開朗基羅被問及如何完成」大衛」這樣匠心獨具的雕刻做品時, 他有一段著名的回答: 「很簡單, 你只要用錘子把石頭上不像大衛的地方敲掉就好了.」 (大道至簡)
  • 解析html的前戲, 磨刀不勿砍柴功:
    1. 尋找」打印此頁」, 或看看網站有沒有html樣式更友好的移動版(將請求頭設置成移動設備的狀態, 而後接收網站移動版)
    2. 需找隱藏在js文件裏的信息,
    3. 網頁信息也許能夠從網頁的url連接中獲取
    4. 尋找其餘數據源, 有沒有其餘網站顯示了一樣的數據? 該網站的數據是否是來自其餘網站
  • css(cascading style sheet, 層疊樣式表)爲爬蟲提供了便利, 它是html元素差別化, 使那些具備相同修飾的元素呈現不一樣的樣式, 從而是爬蟲的目標更明確
  • findAll()的基礎用法: findAll(tag_name, dict_of_attributes)
  • 使用bsObj.tagName只能獲取頁面中第一個指定的標籤
  • get_text()方法正在處理的html文檔中的全部標籤都清楚掉, 返回只包含文字的字符串
  • findAll(tag, attributes, recursive, text, limit, **keywords) & find(tag, attributes, recursive, text, **keywords):
  • tag - 能夠是單個標籤名, 也能夠是多個標籤名組成的列表(集合)
  • attributes - 用字段封裝的標籤屬性與屬性值, 屬性值能夠是一個集合
  • recursive - 遞歸? 默認爲True. 若recursive=False, findAll只會查文檔的一級標籤. 若對速度要求很是高, 可設置遞歸參數
  • text - 用標籤的內容去匹配, 而不是標籤名或屬性,
  • limit - 限制findAll的搜索結果項
  • 關鍵字參數 - 容許用戶本身指定屬性的標籤. 是BeautifulSoup在技術上作的冗餘功能, 任何關鍵字參數能完成的任務, 均可以其餘技術解決
  • 經過標籤參數tag把標籤列表傳到.findAll()裏獲取一列標籤, 實際上是一個」或」關係的過濾器. 而關鍵字參數能夠增長一個」與」關係的過濾器來簡化工做
  • Tag對象 - BeautifulSoup對象經過findfindAll, 或直接調用子標籤獲取的一些列對象或單個對象
  • NavigableString對象 - 用於表示標籤裏的文字
  • Comment對象 - html文檔的註釋標籤
  • html頁面能夠映射成一棵樹
  • 子標籤, 即一個父標籤的下一級; 後代標籤, 指一個父標籤下面全部級別的標籤. 全部子標籤都是後代標籤, 但不是全部的後代標籤都是子標籤
  • 通常, bs函數老是處理當前標籤的後代標籤, 好比.findAll就是遞歸地在全部後代標籤中查找
  • 使用.children將只獲取當前標籤的子標籤, 使用descendants將獲取全部後代標籤
  • 使用.next_siblings將得到當前標籤以後,全部的兄弟標籤. 注意, 對象自己不能做爲本身的兄弟標籤; 從名字也能夠看出, 是返回以後的兄弟標籤. 相應的有previous_siblings,next_siblingprevious_sibling
  • 使用bsObj.find("table", {"id": "giftList"}).tr而不是簡單的bsObj.table.trbsObj.tr是爲了讓對象的選擇更具體, 而不丟失標籤的細節
  • parentparents分別用於獲取標籤對象的直接父標籤和全部父輩標籤(包括爺爺, 但不包括叔叔, 好吧, 通俗易懂)
  • 在動手寫正則表達式以前, 寫一個步驟列表描述出目標字符串的結構
  • regex:
  • * - 重複任意次, 包括0次
  • | - 表示或
  • + - 重複至少1次
  • [] - 匹配其中的任意一個字符
  • () - 表達式編組, 在regex的規則裏編組會優先運行
  • {m,n} - 重複m到n次
  • [^] - 匹配一個任意不在方括號中的字符
  • . - 匹配任意單個字符
  • ^ - 標識字符串的開始
  • \ - 轉義字符
  • $ - 標識字符串的結尾
  • 在BeautifulSoup中使用regex, 提升效率, 如images = bsObj.findAll("img",{"src":re.compile("\.\.imggifts/img.*\.jpg")})
  • regex能夠做爲BeautifulSoup語句的任意一個參數
  • 對於標籤對象, 可採用.attrs獲取所有屬性, 返回字典對象. imgTag.attrs["src"]就能夠獲取圖片的資源位置
  • BeautifulSoup容許將特定函數類型做爲findAll函數的參數, 惟一的限制條件是這些函數必須將一個標籤做爲參數返回結果是布爾類型. BeautifulSoup用這個函數評估遇到的每一個標籤對象, 將評估結果爲」True」的標籤保留下來, 將其餘標籤剔除. 如soup.findAll(lambda tag: len(tag.attrs) == 2)將返回具備2個屬性的標籤
  • BeautifulSoup與regex與lambda的聯合使用, 想一想都無敵
  • 其餘的html解析模塊:
    1. lxml - 底層, 大部分源代碼用c寫成, 所以處理速度會很是快
    2. HTML parser - 自帶的

Chapter3 開始採集

  • 之因此叫網絡爬蟲, 是由於他們能夠沿着網絡爬行, 本質是一種遞歸方式: 爲了找到url連接, 必須首先獲取網頁內容, 檢查頁面內容, 再尋找另外一個url, 獲取頁面內容, 不斷循環
  • 使用網絡爬蟲的時候, 應謹慎地考慮須要消耗多少網絡流量, 還要儘可能思考可否讓採集目標的服務器負載更低
  • 維基百科六度分隔理論 - 任何2個不相干的詞條, 均可以經過總數不超過6條的詞條連接起來(包括原來的2個詞條).
  • 由此, 寫爬蟲時, 如何高效地經過最少的連接點擊次數到達目的站點, 不只使爬蟲工做效率更高, 且對服務器的負載影響也越小
  • 爬取的內容每每攜帶許多無用的信息, 在處理以前, 應根據實際剔除無用信息
  • 隨機算法都努力創造一種均勻分佈且難以預測的數據序列, 但在算法初始階段都須要提供一個隨機數種子(random seed). 徹底相同的種子每次將產生相同的」隨機」數序列. 能夠用系統當前時間做爲隨機數種子, 而使程序運行更具隨機性.
  • python的僞隨機數生成器用的是梅森旋轉算法(https://en.wikipedia.org/wiki/Mersenne_Twister)
  • 淺網(surface web)是搜索引擎能夠抓取的網絡; 暗網(dark web)或深網(deep web)則是另外一部分. 據不徹底統計,互聯網中其實約 90% 的網絡都是深網.
  • 暗網,也被稱爲 Darknet 或 dark Internet,徹底是另外一種「怪獸」。它們也創建在已有的網絡基礎上,可是使用 Tor 客戶端,帶有運行在 HTTP 之上的新協議,提供了一個信息交換的安全隧道。這類暗網頁面也是能夠採集的。
  • 遍歷整個網站的數據採集的好處:
    1. 生成網站地圖(脈絡)
    2. 收集數據
  • 爲了不重複採集頁面, 使用set來保存已採集的頁面
  • 若是遞歸運行的次數過多, 遞歸程序可能會崩潰. python的默認遞歸限制是1000次.
  • 在開始寫爬蟲程序以前, 應充分分析待爬取網站的html文檔的格式
  • 在一個異常處理語句中包裹多行語句顯然是有點危險的. 首先沒法識別出究竟哪行代碼出現了異常, 其次前面的語句出現異常, 將直接致使後面語句的執行
  • 網絡爬蟲位於許多新式的網絡技術領域彼此交叉的中心地帶. 要實現跨站的數據分析, 只要構建出能夠從互聯網上的網頁裏解析和存儲數據的爬蟲就能夠了
  • 一個網站內部的爬蟲, 只須要爬取以/開始的資源就能夠了
  • 在開始寫爬蟲跟隨外鏈隨意跳轉以前, 該思考的問題:
  • 我要收集哪些數據?這些數據能夠經過採集幾個已經肯定的網站(永遠是最簡單的作法)完成嗎?或者個人爬蟲須要發現那些我可能不知道的網站嗎?
  • 當個人爬蟲到了某個網站,它是當即順着下一個出站連接跳到一個新網站,仍是在網站上呆一下子,深刻採集網站的內容?
  • 有沒有我不想採集的一類網站?我對非英文網站的內容感興趣嗎?
  • 若是個人網絡爬蟲引發了某個網站網管的懷疑,我如何避免法律責任?
  • 在以任何正式目的運行代碼以前, 確保已經在可能出現問題的地方都放置了檢查語句
  • 寫代碼以前擬個大綱或畫個流程圖, 是一個很好的編程習慣, 不只能夠爲後期處理節省時間, 更重要的是能夠防止本身在爬蟲變得愈來愈複雜時亂了分寸
  • 重定向 - 容許一個網頁在不一樣的域名下顯示, 有2種形式:
    1. 服務器端重定向, 網頁在加載以前先改變了url
    2. 客戶端重定向, 跳轉到新url以前網頁須要加載內容
  • python3版本的urllib庫會自動處理重定向. 不過要注意,有時候要採集的頁面的 URL 可能並非當前所在頁面的url
  • 爬蟲的一些基本模式: 找出頁面上的全部連接, 區份內外鏈, 跳轉到新的頁面

Chapter4 使用API

  • API的用處:爲不一樣的應用提供了方便友好的接口。不一樣的開發者用不一樣的架構,甚至不一樣的語言編寫軟件都沒問題——由於API設計的目的就是要成爲一種通用語言,讓不一樣的軟件進行信息共享。
  • API 能夠經過 HTTP 協議下載文件,和 URL 訪問網站獲取數據的協議同樣,它幾乎能夠實現全部在網上乾的事情。API 之因此叫 API 而不是叫網站的緣由,實際上是首先 API 請求使用很是嚴謹的語法,其次 API 用 JSON 或 XML 格式表示數據,而不是HTML 格式。
  • 一般api的驗證方法都是用相似令牌(token)的方式調用, 每次api調用將令牌傳遞給服務器. token除了在url連接中傳遞, 還會經過請求頭裏的cookie將用戶信息傳遞給服務器:
token = token
webRequest = urllib.request.Request("http://xxx", headers={"token": token})
  • api一個重要的特徵是反饋格式友好的數據, xml或json. 目前json比xml更受歡迎, 由於json文件比完整的xml文件小, 另外一個緣由是網絡技術的改變.
  • 使用get請求獲取數據時, 用url路徑描述獲取的數據範圍, 查詢參數能夠做爲過濾器或附加請求使用.
  • 一些api使用文件路徑形式指定api版本, 數據和其餘屬性:
http://socialmediasite.com/api/v4/json/users/1234/posts?from=08012014&to=08312014
  • 一些api經過請求參數的形式指定數據格式和api版本:
http://socialmediasite.com/users/1234/posts?format=json&from=08012014&to=08312014
  • response.read() -> bytes
  • python將json轉換成字典, json數組轉換成列表, json字符串轉換成pyton字符串
  • 若是你用API做爲惟一的數據源,那麼你最多就是複製別人數據庫裏的數據,不過都是些已經公佈過的「黃花菜」。真正有意思的事情,是把多個數據源組合成新的形式,或者把 API 做爲一種工具,從全新的視角對採集到的數據進行解釋
  • 雖然列表迭代速度更快, 但集合查找速度更快(肯定一個對象是否在集合中).
  • python的集合就是值爲None的字典, 用到是hash表結構, 查詢速度爲O(1)
  • 多種技術的融合, 多種數據的融合, 將獲得更有用的信息

Chapter5 存儲數據

  • 大數據存儲與數據交互能力, 在新式的程序開發中已是重中之重了.
  • 存儲媒體文件的2種主要方式: 只獲取url連接, 或直接將源文件下載下來
  • 直接引用url連接的優勢:
  • 爬蟲運行得更快,耗費的流量更少,由於只要連接,不須要下載文件。
  • 能夠節省不少存儲空間,由於只須要存儲 URL 連接就能夠。
  • 存儲 URL 的代碼更容易寫,也不須要實現文件下載代碼。
  • 不下載文件可以下降目標主機服務器的負載。
  • 直接引用url連接的缺點:
  • 這些內嵌在網站或應用中的外站 URL 連接被稱爲盜鏈(hotlinking), 每一個網站都會實施防盜鏈措施。
  • 由於連接文件在別人的服務器上,因此應用就要跟着別人的節奏運行了。
  • 盜鏈是很容易改變的。若是盜鏈圖片放在博客上,要是被對方服務器發現,極可能被惡搞。若是 URL 連接存起來準備之後再用,可能用的時候連接已經失效了,或者是變成了徹底無關的內容。
  • python3的urllib.request.urlretrieve能夠根據文件的url下載文件:
from urllib.request import urlretrieve from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen("http://www.pythonscraping.com") bsObj = BeautifulSoup(html) imageLocation = bsObj.find("a", {"id": "logo"}).find("img")["src"] urlretrieve (imageLocation, "logo.jpg") 
  • csv(comma-separated values, 逗號分隔值)是存儲表格數據的經常使用文件格式
  • 網絡數據採集的一個經常使用功能就是獲取html表格並寫入csv
  • 除了用戶定義的變量名,mysql是不區分大小寫的, 習慣上mysql關鍵字用大寫表示
  • 鏈接與遊標(connection/cursor)是數據庫編程的2種模式:
  • 鏈接模式除了要鏈接數據庫以外, 還要發送數據庫信息, 處理回滾操做, 建立遊標對象等
  • 一個鏈接能夠建立多個遊標, 一個遊標跟蹤一種狀態信息, 好比數據庫的使用狀態. 遊標還會包含最後一次查詢執行的結果. 經過調用遊標函數, 如fetchall獲取查詢結果
  • 遊標與鏈接使用完畢以後,務必要關閉, 不然會致使鏈接泄漏, 會一直消耗數據庫資源
  • 使用try ... finally語句保證數據庫鏈接與遊標的關閉
  • 讓數據庫更高效的幾種方法:
    1. 給每張表都增長id字段. 一般數據庫很難智能地選擇主鍵
    2. 用智能索引, CREATE INDEX definition ON dictionary (id, definition(16));
    3. 選擇合適的範式
  • 發送Email, 經過爬蟲或api獲取信息, 設置條件自動發送Email! 那些訂閱郵件, 確定就是這麼來的!

Chapter6 讀取文檔

  • 互聯網的最基本特徵: 做爲不一樣類型文件的傳輸媒體
  • 互聯網不是一個html頁面的集合, 它是一個信息的集合, 而html文件只是展現信息的一個框架
  • 從最底層的角度看, 全部文檔都是01的編碼, 而任意類型的文件的惟一區別就在於,它們的01在面向用戶的轉換方式不一樣
  • utf-8的全稱: Universal Character Set - Transformation Format 8 bit
  • utf-8的每一個字符開頭有一個標記,表示該字符用幾個字節表示.一個字符最多能夠是4字節, 但字節信息裏還包括一部分設置信息, 所以所有32位不會都用, 最多使用21位
  • utf8利用ascii的填充位讓全部以」0」開頭的字節表示該字符佔用1個字節. 所以, 在英文字符在ascii和uft8兩個編碼方式下表示同樣
  • python默認將文本讀成ascii編碼格式
  • utf8不能處理iso編碼格式. 所以作數據採集工做時,尤爲對國際網咱, 最好先看看meta標籤內容, 用網站推薦的編碼方式讀取頁面內容
  • 幾種讀取在線文件的方法:
    1. 下載讀取
    2. 從網上直接將文件讀成一個字符串, 而後將其轉換成一個StringIO對象, 使其具備文件的屬性:
dataFile = io.StringIO(data) 
  • csv.reader的返回對象是可迭代的, 並且由list對象構成.
  • csv.DictReader將csv文件的每一行轉換成python字典返回, 並將字段列表(標題欄)保存在dictReader.fieldnames裏
  • pdf的文字提取
  • .docx的文字提取:
    1. 從文件讀取xml, 將文檔讀成一個二進制對象(BytesIO), 再用zipfile解壓(全部.docx文件爲了節省空間都進行過壓縮), 再讀取解壓文件, 就變成了xml
from zipfile import ZipFile from urllib.request import urlopen from io import BytesIO wordFile = urlopen("http://pythonscraping.com/pages/AWordDocument.docx").read() wordFile = BytesIO(wordFile) document = ZipFile(wordFile) xml_content = document.read("word/document.xml") print(xml_content.decode("utf-8")) 

Part2 高階數據採集

  • 網站的真實故事其實都隱藏在js, 登陸表單和網站反爬取措施的背後

Chapter7 數據清洗

  • 用regex移除不想要的字符, 如換行符(\n). 剔除字符的過程, 合理的前後順序能省不少力
  • 先以utf8格式編碼,再以ascii方法解碼的方式,能夠必定程度上剔除unicode字符
  • 數據標準化要確保清洗後的數據在語言學或邏輯上是等價的
  • python的OrderedDict,能解決字典無序排列的問題
  • 數據標準化時,根據投入計算能力的多少,還能夠再考慮大小寫(python與Python),單詞等價(1st與first),連字符的使用(co-ordinated與coordinated),拼寫錯誤,語病等因素
  • 對連字符的一個處理是,將其去掉或轉換成其餘字符,好比空格

Chapter8 天然語言處理

歸納數據

  • n-gram模型可用於詞頻分析, 很厲害!

馬爾可夫模型

  • 馬爾可夫文字生成器(markov text generator) - 基於一種經常使用於分析大量隨機事件的馬爾可夫模型. 隨機事件的特色是一個離散事件發生以後, 另外一個離散事件將在前一個事件的條件下以必定機率發生
  • 在馬爾可夫模型描述的天氣系統中,若是今天是晴天,那麼明天有70%的多是晴天,20%的可能多雲,10% 的可能下雨。若是今天是下雨天,那麼明天有 50% 的可能也下雨,25% 的多是晴天,25% 的多是多雲
  • 馬爾可夫模型須要注意的點:
  • 任何一個節點引出的全部可能的總和必須等於 100%。不管是多麼複雜的系統,必然會在下一步發生若干事件中的一個事件。
  • 只有當前節點的狀態會影響下一個狀態。
  • 有些節點可能比其餘節點較難到達
  • google的pagerank算法也是基於馬爾可夫模型的, 將網站看做節點, 入站/出站連接做爲節點的連線. 鏈接某個節點的可能性(linklihood)表示一個網站的相對關注度
  • 馬爾可夫文字生成器的工做原理: 對文獻中的每個單詞進行有效處理, 再創建一個二維字典, 用於統計二元詞組的詞頻. 每次以當前單詞所在節點爲查詢表, 選擇下一個節點. 隨機生成一個權重, 用詞頻減權重, 一旦權重減爲非正數, 肯定該單詞爲下一單詞. 詞頻高的單詞使權重減少得更厲害, 所以更容易得到
  • 在尋找有向圖的最短路徑問題中, 效果最好且最經常使用的方法是廣度優先搜索(breadth-first search, bfs)

天然語言處理

  • 哪些單詞使用得最頻繁?哪些單詞用得最少?一個單詞後面跟着哪幾個單詞?這些單詞是如何組合在一塊兒的?
  • nltk, 用於識別和標記英語文本中各詞的詞性.
  • nltk很擅長生成一些統計信息,包括對一段文字的單詞數量單詞頻率單詞詞性的統計
  • 用nltk作統計分析通常從Text對象開始`
from nltk import word_tokenize from nltk import Text tokens = word_tokenize("Here is some not very interesting text") text = Text(tokens) 
  • word_tokenize函數的參數能夠是任何python字符串, 其將字符串按語義分割成單詞
  • 文本對象能夠像普通的python list那樣操做, 好像它們就是一個包含文本里全部單詞的list同樣.
  • 將文本對象放到一個頻率分佈對象FreqDist中, 可查看哪些單詞是最經常使用的, 以及單詞的頻率等
  • bigrams模塊的bigrams函數做用於文本對象, 獲得一個bigrams(2-gram)的生成器對象, 其也能夠做爲參數傳入FreqDist, 獲得頻率分佈對象
  • 更通常的狀況, 能夠導入ngrams模塊, ngrams函數被用來將文本對象分解成任意規模的n-gram序列,
  • nltk庫設計了許多不一樣的工具和對象來組織, 統計, 排序和度量大段文字的含義
  • nltk默認使用賓夕法尼亞大學Penn Treebank項目的語料標記部分
  • nltk能夠用它的超級大字典分析文本內容, 幫助尋找單詞的含義. nltk的一個基本功能是識別句子中各個詞的詞性
  • nltk用英語的上下文無關文法(context-free grammar)識別詞性. 上下文無關文法基本上能夠當作一個規則集合,用一個有序的列表肯定一個詞後面能夠跟哪些詞
  • nltk進行訓練, 建立一個全新的上下文無關文法規則, 好比用Penn Treebank詞性標記手工完成語言的大部分文本的語義標記, 將結果傳給nltk, 訓練它對未標記文本的語義標記.
  • 網絡數據採集常常須要處理搜索的問題, 好比採集的文字的詞性, 舉例, 但願採集是動詞飛的fly, 而過濾掉名詞蒼蠅的fly
  • 天然語言中的許多歧義問題均可以用nltkpos_tag解決, 不僅是搜索目標單詞或短語, 而是搜索帶標記的目標單詞或短語,這樣能夠大大提升爬蟲搜索的準確率和效率

Chapter9 穿越網頁表單與登陸窗口進行採集

  • 利用post方法, 將信息推送到服務器進行存儲與分析
  • 頁面表單基本上能夠當作一種用戶提交post請求的方式, 且這種請求方式是服務器可以理解和使用的

Requests庫

  • Requests庫是一個擅長處理複雜的http請求, cookie, header等內容的第三方庫

提交一個基本表單

  • 大多數網頁表單都是由一些 HTML 字段、一個提交按鈕、一個在表單處理完以後跳轉的「執行結果」(表單屬性 action 的值)頁面構成。
  • 字段的名稱決定了表單被確認後要被傳送到服務器上的變量名稱
  • 表單的真實行爲發生在action指定的頁面
  • HTML 表單的目的,只是幫助網站的訪問者發送格式合理的請求,向服務器請求沒有出現的頁面
  • 大多數狀況下, 提交表單只須要注意:
    1. 提交數據的字段名稱
    2. 表單的action屬性, 即表單提交後網站會顯示的頁面

單選按鈕, 複選框和其餘輸入

  • 不管表單的字段看起來多麼複雜,仍然只有兩件事是須要關注的:字段名稱。字段名稱能夠經過查看源代碼尋找 name 屬性輕易得到
  • 字段的值有時會比較複雜. 若是不肯定一個輸入字段指定數據格式, 可跟蹤瀏覽器正在經過網站發出或接受的get和post請求的內容.
  • 跟蹤get請求效果最好也最直接的手段是看網站的url連接, ?xxx=xxx&xxx=...
  • 複雜的post表單, 可查看瀏覽器向服務器傳遞的參數, 用chrome的F12

提交文件和圖像

  • requests處理文件上傳的方式與提交普通表單相似:
import requests file = {"image": open("filename", "rb")} response = requests.post("http://...", data = file) 
  • 大多數新式的網站都用 cookie 跟蹤用戶是否已登陸的狀態信息。一旦網站驗證了登陸權證,它就會將它們保存在瀏覽器的 cookie 中,裏面一般包含一個服務器生成的令牌登陸有效時限狀態跟蹤信息。網站會把這個 cookie 看成信息驗證的證據,在你瀏覽網站的每一個頁面時出示給服務器。
  • obj.cookies.method從響應中獲取cookie, 再經過cookies參數將cookie發送給服務器
  • 使用session對象, 能夠持續跟蹤會話信息, 好比cookie, header, 甚至運行http協議的信息.
  • 使session的方法就是, 建立Session對象, 再用Session對象發送請求
  • 寫爬蟲時, 應持續關注cookie的狀態, 掌握它們在可控範圍內很是重要. 這樣能夠避免痛苦地調試和追尋網站行爲異常,節省不少時間。
  • 在cookie發明以前, 處理網站登陸經常使用的方法是用http基本接入認證(http basic access authentication), requests庫的auth模塊專門用來處理http認證:
import requests from requests.auth import AuthBase from requests.auth import HTTPBasicAuth auth = HTTPBasicAuth('ryan', 'password') r = requests.post(url="http://pythonscraping.com/pages/auth/login.php", auth=auth) # HTTPBasicAuth對象做爲auth參數傳遞到請求 

其餘表單問題

  • 表單是網絡惡意機器人(malicious bots)酷愛的網站切入點。
  • 新式的網站常常在HTML 中使用不少安全措施,讓表單不能被快速穿越

Chapter10 採集 JavaScript

  • JavaScript 是網絡上最經常使用也是支持者最多的客戶端腳本語言。它能夠收集用戶的跟蹤數據,不須要重載頁面直接提交表單,在頁面嵌入多媒體文件,甚至運行網頁遊戲

JavaScript 簡介

  • JavaScript 是一種弱類型語言, 全部變量都用var關鍵字進行定義, 能夠將函數做爲變量使用
  • 經常使用的 JavaScript 庫
    1. jQuery:
      • 一個網站使用jQuery的特徵是源代碼裏包含了jQuery入口.
      • jQuery 能夠動態地建立 HTML 內容,只有在 JavaScript 代碼執行以後纔會顯示。若是用傳統的方法採集頁面內容,就只能得到 JavaScript 代碼執行以前頁面上的內容
      • 這些頁面還可能包含動畫、用戶交互內容和嵌入式媒體,這些內容對網絡數據採集都是挑戰。
    2. Google Analytics
      • 若是網站使用了Google Analytics,在頁面底部會有相似<!-- Google Analytics -->的 JavaScript 代碼
      • 若是一個網站使用了 Google Analytics 或其餘相似的網絡分析系統,而不想讓網站知道在採集數據,就要確保把那些分析工具的 cookie 或者全部 cookie 都關掉。
    3. Google Map
      • 在 Google 地圖上,顯示一個位置最經常使用的方法就是用標記
var marker = new google.maps.Marker({
    position: new google.maps.LatLng(-25.363882,131.044922),
    map: map,
    title: 'Some marker text'
});
  • 取出google.maps.LatLng()裏的座標, 生成一組經緯度座標值, 再經過google的地理座標反向查詢api(https://developers.google.com/maps/documentation/javascript/examples/geocoding-reverse), 就能夠將經緯度座標組解析成格式規範的地址, 可存儲或分析

ajax和動態html

  • 提交表單以後,或從服務器獲取信息以後,網站的頁面不須要從新刷新,那麼訪問的網站就在用 Ajax 技術。
  • Ajax(Asynchronous JavaScript and XML) 其實並非一門語言,而是用來完成網絡任務的一系列技術, 網站不須要使用單獨的頁面請求就能夠和網絡服務器進行交互
  • 動態 HTML(dynamic HTML,DHTML)也是一系列用於解決網絡問題的技術集合。DHTML 是用客戶端語言改變頁面的 HTML 元素(HTML、CSS,或者兩者皆被改變). 是否使用了DHTML, 關鍵要看有沒有用 JavaScript 控制 HTML 和 CSS 元素
  • 有時,網頁用一個加載頁面把你引到另外一個頁面上,可是網頁的 URL 連接在這個過程當中一直沒有變化。
  • 當用爬蟲採集的網頁內容與瀏覽器上顯示的不一樣時, 是由於爬蟲不能執行 JavaScript 代碼, 而瀏覽器能夠正確地執行 JavaScript .
  • 用python爬取使用了ajaxdhtml的頁面的2種辦法:
    1. 直接從 JavaScript 代碼裏採集內容
    2. 用第三方庫運行 JavaScript , 直接採集在瀏覽器中看到的頁面

Selenium

  • Selenium是一個網絡數據採集工具, 其最初是爲網站自動化測試而開發的, 近幾年,它還被普遍用於獲取精確的網站快照.
  • Selenium能夠直接運行在瀏覽器上, 它可讓瀏覽器自動加載頁面, 獲取須要的數據, 甚至頁面截屏, 或者判斷網站上某些動做是否發生
  • Selenium須要與第三方瀏覽器結合使用.
  • PhantomJS能夠將網站加載到內存並執行頁面上的 JavaScript, 但它不會向用戶展現網頁的圖形界面.
  • 把 Selenium 和 PhantomJS 結合在一塊兒,就能夠運行一個很是強大的網絡爬蟲了,能夠處理cookieJavaScripheader,以及任何須要作的事情
  • python的Selenium庫是一個在WebDriver上調用的api, webdriver有點像加載網站的瀏覽器, 能夠像BeautifulSoup對象同樣用來查找頁面元素, 與頁面上的元素進行交互, 以及執行其餘動做來運行爬蟲
  • webdriver的page_source函數返回頁面的源代碼字符串. 若不想要Selenium選擇器, 則能夠用返回的源代碼建立BeautifulSoup對象.
  • 頁面的加載時間是不肯定的, 具體依賴於服務器某一毫秒的負載狀況, 以及不斷變化的網速
  • 解決頁面加載時間不肯定的有效方法是, 讓Selenium不斷檢查某個元素是否存在, 以肯定頁面是否徹底加載, 若是頁面加載成功, 就執行後續程序.
  • WebDriverWaitexpected_conditions組合構成了Selenium的隱式等待(implicit wait).
  • 隱式等待顯式等待的不一樣之處在於,隱式等待是等 DOM 中某個狀態發生後再繼續運行代碼(沒有明確的等待時間,可是有最大等待時限,只要在時限內就能夠),而顯式等待明確設置了等待時間。在隱式等待中,DOM 觸發的狀態用expected_conditions 定義
  • Selenium中元素被觸發的指望條件有許多種, 包括
  • 彈出一個提示框
  • 一個元素被選中(好比文本框)
  • 頁面的標題改變了,或者某個文字顯示在頁面上或者某個元素裏
  • 一個元素在 DOM 中變成可見的,或者一個元素從 DOM 中消失了
  • 大多數指望的條件在使用前須要指定等待的目標元素, 元素用定位器指定.
  • 定位器是一種抽象的查詢語言,用 By 對象表示,能夠用於不一樣的場合,包括建立選擇器(driver.find_element(By.ID, 「content」))
  • 若是能夠不用定位器, 就不用, 畢竟能夠少導入一個模塊
  • Xpath(XML Path)是在xml文檔中導航和選擇元素的查詢語言. BeautifulSoup不支持Xpath. 使用方法一般和css選擇器同樣.
  • Xpath語法中四個重要概念:
    1. 根節點與非根節點
      • /div 選擇 div 節點,只有當它是文檔的根節點時
      • //div 選擇文檔中全部的 div 節點(包括非根節點)
    2. 經過屬性選擇節點
      • //@href 選擇帶 href 屬性的全部節點
      • //a[@href=’http://google.com’] 選擇頁面中全部指向 Google 網站的連接
    3. 經過位置選擇節點
      • //a[3] 選擇文檔中的第三個連接
      • //table[last()] 選擇文檔中的最後一個表
      • //a[position() < 3] 選擇文檔中的前三個連接
    4. *(星號)匹配任意字符或節點, 能夠在不一樣條件下使用
      • //table/tr/* 選擇全部表格行 tr 標籤的全部的子節點(這很適合選擇 th 和 td 標籤)
      • //div[@*] 選擇帶任意屬性的全部 div 標籤
  • 微軟的Xpath語法頁面https://msdn.microsoft.com/en-us/enus/library/ms256471

處理重定向

  • 客戶端重定向是在服務器將頁面內容發送到瀏覽器以前,由瀏覽器執行 JavaScript 完成的頁面跳轉,而不是服務器完成的跳轉
  • 客戶端重定向redirect, 即服務器在返回的響應中告知客戶端請求資源的正確url, 並設置狀態碼3xx. 客戶端根據響應結果對新的url發起請求
  • 服務器重定向dispatch, 指服務器在處理請求的過程當中將請求前後分發(委託)給其餘部件處理的過程. 服務器內部如何操做, 不能知道也不須要知道吧
  • 服務器重定向可經過python的urllib庫解決
  • 利用Selenium執行 JavaScript 代碼, 解決客戶端重定向問題. 關鍵點在於什麼時候中止頁面監控. 一種方法是: 從頁面開始加載時就「監視」DOM 中的一個元素,而後重複調用這個元素直到Selenium拋出一個StaleElementReferenceException異常;也就是說,元素不在頁面的 DOM 裏了,說明這時網站已經跳轉

Chapter11 圖像識別與文字處理

  • 當不想讓文字被爬蟲採集時, 將文字作成圖片放在網頁上是經常使用的方法

OCR(Optical Character Recognition, 光學文字識別)

  • 利用Pillow完成圖片的預處理, 讓機器能夠更方便地讀取圖片
  • Tesseract是一個ocr庫, 高精確度, 高靈活性, 能夠經過訓練識別出任何字體以及任何unicode字符
  • Tesseract是一個python的命令行工具, 經過tesseract命令在python外運行
  • NumPy庫具備大量線性代數以及大規模科學計算的方法, 其能夠用數學方法將圖片表示成巨大的像素數組

處理格式規範的文字

  • 格式規範的文字的特色:
  • 使用一個標準字體(不包含手寫體、草書,或者十分「花哨的」字體)
  • 雖然被複印或拍照,字體仍是很清晰,沒有多餘的痕跡或污點
  • 排列整齊,沒有歪歪斜斜的字
  • 沒有超出圖片範圍,也沒有殘缺不全,或牢牢貼在圖片的邊緣
  • 對於難於辨認的圖片, 先對圖片進行預處理, 可大大提升圖文轉換的正確率
  • Tesseract最大的缺點是對漸變背景色的處理, 它的算法在讀取文件以前自動嘗試調整圖片對比度
  • 使用Selenium + Tesseract從網站圖片中抓取文- 對於難於辨認的圖片, 先對圖片進行預處理, 可大大提升圖文轉換的正確率
  • 經過給 Tesseract 提供大量已知的文字與圖片映射集,通過訓練 Tesseract 就能夠「學會」識別同一種字體,並且能夠達到極高的精確率和準確率,甚至能夠忽略圖片中文字的背景色和相對位置等問題。

讀取驗證碼與訓練Tessract

  • CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart, 全自動區分計算機與人類的圖靈測試), 簡稱驗證碼, 其目的是爲了阻止網絡訪問
  • 要訓練Tesseract識別一種文字, 都須要向其提供每一個字符不一樣形式的樣本:
    1. 將大量驗證碼樣本下載到一個目錄, 樣本數量由驗證碼的複雜程度決定.(用驗證碼的真實結果給每一個樣本文件命名)
    2. 準確地告訴tesseract一張圖片中的每一個字符是什麼, 以及每一個字符的具體位置. 這時要建立一些矩形定位文件, 一個驗證碼圖片生成一個矩形定位文件(字符 + 包圍字符的最小矩形的左下角和右上角座標 + 圖片樣本的編號)(http://pp19dd.com/tesseract-ocr-chopper/ 在線轉換工具)
    3. 矩形定位文件必須保存爲一個.box的文本文件, 一樣用驗證碼的實際結果命名
    4. 備份
    5. 用同時包含驗證碼圖片和.box文件的目錄, 建立訓練文件, 即.tessdata文件

獲取驗證碼提交答案

  • 大多數網站生成的驗證碼圖片都具備如下屬性。
  • 它們是服務器端的程序動態生成的圖片。驗證碼圖片的 src 屬性可能和普通圖片不太同樣,可是能夠和其餘圖片同樣進行下載和處理。
  • 圖片的答案存儲在服務器端的數據庫裏。
  • 不少驗證碼都有時間限制,若是你太長時間沒解決就會失效。雖然這對網絡機器人來講不是什麼問題,可是若是你想保留驗證碼的答案一下子再使用,或者想經過一些方法延長驗證碼的有效時限,可能很難成功。
  • 經常使用的處理方法就是,首先把驗證碼圖片下載,清理乾淨,而後用 Tesseract 處理圖片,最後返回符合網站要求的識別結果。

Chapter12 避開採集陷阱

道德規範

  • 在採集那些不想被採集的網站時, 可能存在一些很是符合道德和法律規範的理由
  • 大多數網絡機器人一開始都只能作一些寬泛的信息和漏洞掃描

讓網絡機器人看起來像人類用戶

  • requests模塊除了處理網站的表單, 仍是設置請求首部的利器.
  • 7個被大多數瀏覽器用來初始化全部網絡請求的請求報文首部字段:
    1. Host : http://kissg.me
    2. Connection : keep-alive
    3. Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp
    4. User-Agent : Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/39.0.2171.95 Safari/537.36
    5. Referrer : https://kissg.me/
    6. Accept-Encoding : gzip,deflate,sdch
    7. Accept-Language : en-US,en
  • 經典的python爬蟲在使用urllib標準庫時, 都會發送Accept-Encoding=identity;User-Agent=Python-urllib/3.4的請求頭
  • 雖然網站可能會對http請求首部的每一個字段進行」是否具備人性」的檢查, 但最重要的參數是」User-Agent」
  • 在處理一些警覺性很是高的網站, 要注意常常用卻不多檢查的首部字段, 好比Accept-Language
  • 請求頭的不一樣, 可讓網站改變內容的佈局, 好比User-Agent設置成移動設備的首部, Accpet-Language設置成另外一種語言
  • 可 以 調 用 delete_cookie() 、 add_cookie() 和 delete_all_cookies() 方 法 來 處 理cookie。另外,還能夠保存 cookie 以備其餘網絡爬蟲使用
  • 有時候須要增長時延, 來使爬蟲假裝得更像人類
  • 多線程爬蟲, 一個線程處理數據, 另外一個加載數據(我之前想的提升爬取速度的方法大體也是這樣)

常見表單安全措施

  • 在html表單中, 隱含字段可讓字段對瀏覽器可見, 而對用戶不可見. 隨着愈來愈多的網站開始用 cookie 存儲狀態變量來管理用戶狀態,在找到另外一個最佳用途以前,隱含字段主要用於阻止爬蟲自動提交表單
  • 用隱含字段阻止網絡數據採集的2種方式:
    1. 使表單頁面上的一個字段能夠用服務器生成的隨機變量表示. 解決辦法就是先採集表單頁面上的這個隨便變量, 再與其餘表單數據一併提交
    2. 蜜罐(honey pot), 故意設一個隱含字段, 服務器將自動忽略這些字段的真實值, 但全部填寫了隱含字段的用戶可能被封殺. 說白了, 就是爲爬蟲故意設的字段, 通常用戶看不到, 也就不會填
  • 若是隱含字段帶有較大的隨機字符串變量, 則可能網絡服務器會在表單提交時檢查它們. 另外還有一些檢查, 用來保證當前生成的表單變量只被使用一次或是最近生成的
  • html+css隱藏元素的方法:
    1. 經過簡單css屬性設置進行隱藏
    2. 隱含輸入字段
    3. 設置元素的位置超出瀏覽器邊界, 並隱藏滾動條
  • Selenium能夠獲取訪問頁面的內容, 所以它能夠區分頁面上的可見與不可見元素, 經過is_displayed()能夠判斷元素在頁面上是否可見. 連第3種方式隱藏的元素都能被揪出來!
  • 在提交表單以前, 確認已經在表單中, 準備提交的隱含字段的值(或者讓Selenium自動提交)

問題檢查表

  • 首先,若是從網絡服務器收到的頁面是空白的,缺乏信息,或其遇到他不符合預期的狀況(或者不是在瀏覽器上看到的內容),有多是由於網站建立頁面的 JavaScript執行有問題
  • 若是準備向網站提交表單或發出 POST 請求,記得檢查一下頁面的內容,看看想提交的每一個字段是否是都已經填好,並且格式也正確。用 chrome 瀏覽器的網絡面板(快捷鍵 f12 打開開發者控制檯,而後點擊「network」便可看到)查看發送到網站的 POST命令,確認每一個參數都是正確的。
  • 若是已經登陸網站卻不能保持登陸狀態,或者網站上出現了其餘的「登陸狀態」異常,請檢查 cookie。確認在加載每一個頁面時 cookie 都被正確調用,並且 cookie 在每次發起請求時都發送到了網站上。
  • 若是在客戶端遇到了 HTTP 錯誤,尤爲是 403 禁止訪問錯誤,這可能說明網站已經把此 IP 看成機器人了,再也不接受任何請求。要麼等待 IP 地址從網站黑名單裏移除,要麼就換個 IP 地址. 若是你肯定本身並無被封殺,那麼再檢查下面的內容。
  • 確認爬蟲在網站上的速度不是特別快。快速採集是一種惡習,會對網管的服務器形成沉重的負擔,還會讓本身陷入違法境地,也是 IP 被網站列入黑名單的首要緣由。給爬蟲增長延遲,讓它們在夜深人靜的時候運行。切記:匆匆忙忙寫程序或收集數據都是拙劣項目管理的表現;應該提早作好計劃,避免臨陣慌亂
  • 還有一件必須作的事情:修改你的請求頭!有些網站會封殺任何聲稱本身是爬蟲的訪問者。若是不肯定請求頭的值怎樣纔算合適,就用瀏覽器的請求頭
  • 確認沒有點擊或訪問任何人類用戶一般不能點擊或接入的信息
  • 若是用了一大堆複雜的手段才接入網站,考慮聯繫一下網管吧,告訴他們目的。試試發郵件到 webmaster@< 域名 > 或 admin@< 域名 >,請求網管容許你使用爬蟲採集數據。管理員也是人嘛!

用爬蟲測試網站

  • 當研發一個技術棧較大的網絡項目時,常常只對棧底(項目後期用的技術)進行一些常規測試.
  • 網站一般是不一樣標記語言額編程語言的大雜燴. 這使網站的前端測試自動化變得困難. 好比, 爲 JavaScript 部分寫單元測試,但沒什麼用,若是 JavaScript 交互的 HTML 內容改變了,那麼即便 JavaScript 能夠正常地運行,也不能完成網頁須要的動做

測試簡介

  • 一個單元測試一般包含如下特色:
  • 每一個單元測試用於測試一個組件(component). 一般一個組件的全部單元測試都集成在同一個類裏
  • 每一個單元測試均可以徹底獨立地運行, 一個單元測試須要的全部啓動(setup)和卸載(teardown)都必須經過這個單元測試自己去處理. 單元測試不能對其餘測試形成干擾, 並且不管按何種順序排列, 都必須可以正常運行
  • 每一個單元測試一般至少含有一個斷言
  • 單元測試與生產代碼是分離的. 雖然它們須要導入而後在待測試的代碼中使用,可是它們通常被保留在獨立的類和目錄中。

python單元測試

  • python的單元測試模塊unittest. 只要先導入模塊而後繼承unittest.TestCase類, 就可實現:
    1. 爲每一個單元測試的開始和結束提供setUptearDown函數
    2. 提供不一樣類型的斷言
    3. 將全部以test_開頭的函數看成單元測試運行, 忽略不帶test_的函數
  • setUpClass函數只在類的初始化階段運行一次, setUp函數在每一個測試啓動時都運行.

Selenium單元測試

  • Selenium是一個能夠解決網站上各類複雜問題的優秀測試框架, 初衷就是用來作網站測試
  • Selenium能夠在瀏覽器上作任何事情, 包括輸入, 點擊等, 這樣就能夠找出異常表單, JavaScript 代碼錯誤, html排版錯誤, 以及其餘用戶使用過程當中可能出現的問題
  • Selenium測試的關鍵是element. 能夠對任何給定元素作許多操做, 如:
    1. myElement.click()
    2. myElement.click_and_hold()
    3. myElement.release()
    4. myElement.double_click()
    5. myElement.send_keys_to_element(「content to enter」()
  • 爲了一次性完成一個元素的多個操做, 能夠用行爲連(action chain)儲存多個操做, 而後在程序中執行屢次
  • .drag_and_drop實現拖拽, 可用於一部分登陸驗證
  • driver.get_screenshot_as_file("xxx")截屏

Python單元測試與Selenium單元測試的選擇

  • Python 的單元測試語法嚴謹冗長,更適合爲大多數大型項目寫測試
  • Selenium 的測試方式靈活且功能強大, 能夠成爲一些網站功能測試的首選
  • 用Selenium能夠輕易獲取網站的信息, 而單元測試能夠評估信息是否知足測試條件, 兩者組合是最佳搭檔
  • 任何網站上能看到的內容均可以經過Python的單元測試和Selenium組合來測試

Chapter14 遠程採集

  • 當你中止在本身的筆記本上運行python爬蟲, 生活會變得更加輕鬆

爲何要用遠程服務器

  • 創建爬蟲的第一原則是: 全部信息均可以僞造. 能夠用非本人的郵箱發送郵件, 經過命令自動化鼠標行爲
  • 阻止網站被採集的注意力主要集中在識別人類與機器人的行爲差別上面

Tor代理服務器

  • 洋蔥路由(The Onion Router)網絡,是一種IP地址匿名手段。經過不一樣服務器構成多個層(就像洋蔥)把客戶端包在最裏面。數據進入網絡以前會被加密,所以任何服務器都不能偷取通訊數據
  • 雖然 Tor 網絡可讓你訪問網站時顯示的 IP 地址是一個不能跟蹤到你的 IP 地址,可是你在網站上留給服務器的任何信息都會暴露你的身份。
  • 登陸 Tor 網絡不是一個自動的匿名措施,也不能讓你進入互聯網上任何區域。雖然它是一個實用的工具,可是用它的時候必定要謹慎、清醒,而且遵照道德規範
  • 當你用 Tor 的時候網速會變慢。這是由於代理有可能要先在全世界網絡上轉幾回纔到目的地!
  • tor服務必須運行在9150端口上
  • PySocks是一個代理服務器通訊模塊, 可與tor配合使用
  • tor中使用seleniumphantomjs, 不須要pysocks, 只要保證tor在運行, 而後增長service_args參數設置代理端口, 讓selenium經過端口9150鏈接網站就能夠了

互聯網其實就是一個用戶界面不太友好的超級APIjavascript

The Zen of Python

Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren’t special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one– and preferably only one –obvious way to do it. Although that way may not be obvious at first unless you’re Dutch. Now is better than never. Although never is often better than right now. If the implementation is hard to explain, it’s a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea – let’s do more of those!php

優美勝於醜陋 明瞭勝於隱晦 簡潔勝於複雜 複雜勝於混亂 扁平勝於嵌套 寬鬆勝於緊湊 可讀性很重要 即使是特例,也不可違背這些規則 雖然現實每每不那麼完美 可是不該該放過任何異常 除非你肯定須要如此 若是存在多種可能,不要猜想 確定有一種——一般也是惟一一種——最佳的解決方案 雖然這並不容易,由於你不是Python之父 1 動手比不動手要好 但不假思索就動手還不如不作 若是你的方案很難懂,那確定不是一個好方案 若是你的方案很好懂,那確定是一個好方案 命名空間很是有用,咱們應當多加利用css

互聯網簡介

  • 互聯網是一種信息交換形式
  • 當http從瀏覽器收到一個數據包, 數據包的內容必定被當作一個網站, 網站的結構由html構成
  • 雖然html一般被當作是編程語言, 但它實際是一個標記語言, 經過標籤訂義文檔等結構以肯定各個元素
  • css是配合html對網站樣式進行定義的語言, 其爲網站對象定義顏色, 位置, 尺寸和背景等屬性

網絡數據採集的法律和道德約束

  • 知識產權分3種基本類型: 商標(^TM或®), 版權(©), 專利.
  • 專利用來聲明內容全部權僅屬於發明者
  • 商標是一個單詞, 詞組, 符號或設計, 用來識別和區分一種商品的來源. 商標的全部權很大程度上由使用場景決定
  • 只要將一件東西帶到世間, 它就自動受到版權法的保護
  • 版權保護只涉及創造性的做品, 不涉及統計數據或事實, 而許多爬蟲採集的都是事實和統計數據. 若是數據是事實性的信息, 那麼徹底照搬也不違反版權法
  • 若是知足下列條件, 爬蟲算侵犯動產:
    1. 缺乏許可. 若是網站的服務協議條款明確禁止使用爬蟲
    2. 形成實際傷害.
    3. 故意而爲- -
  • 只有三個條件都知足, 纔算侵犯動產.
  • 若是網速正常, 即便一臺pc也能夠給許多網站形成沉重負擔.
  • 真的沒理由去傷害別人的網站
  • 可能能夠在大型網站的根目錄找到robots.txt(我真的在維基百科上找到了!)
  • robots.txt 文件能夠被程序輕易地解析和使用, rebots.txt 文件的語法沒有標準格式。它是一種業內慣用的作法. rebots.txt 文件並非一個強制性約束.
  • robots.txt第一行非註釋內容是 User-agent: ,註明具體哪些機器人須要遵照規則。後面是一組規則 Allow: 或 Disallow: ,決定是否容許機器人訪問網站的該部份內容. 若是一條規則後面跟着一個與之矛盾的規則,則按後一條規則執行.
  • google爬蟲採集網站時, 會爲網站留一個副本, 而後放在互聯網上, 任何人可接入這些緩存. http://webcache.googleusercontent.com/search?q=cache:YourURL
相關文章
相關標籤/搜索