python爬蟲學(xué)習(xí)筆記01

爬蟲簡介

網(wǎng)絡(luò)爬蟲(又被稱為網(wǎng)頁蜘蛛倡勇,網(wǎng)絡(luò)機(jī)器人山害,在FOAF社區(qū)中間,更經(jīng)常的稱為網(wǎng)頁追逐者)冰木,是一種按照一定的規(guī)則穷劈,自動地抓取萬維網(wǎng)信息的程序或者腳本。另外一些不常使用的名字還有螞蟻踊沸、自動索引歇终、模擬程序或者蠕蟲。

其實逼龟,說白了就是爬蟲可以模擬瀏覽器的行為做你想做的事评凝,訂制化自己搜索和下載的內(nèi)容,并實現(xiàn)自動化的操作审轮。比如瀏覽器可以下載小說肥哎,但是有時候并不能批量下載,那么爬蟲的功能就有用武之地了疾渣。

實現(xiàn)爬蟲技術(shù)的編程環(huán)境有很多種篡诽,Java,Python榴捡,C++等都可以用來爬蟲杈女。但是博主選擇了Python,相信很多人也一樣選擇Python吊圾,因為Python確實很適合做爬蟲达椰,豐富的第三方庫十分強(qiáng)大,簡單幾行代碼便可實現(xiàn)你想要的功能项乒,更重要的啰劲,Python也是數(shù)據(jù)挖掘和分析的好能手。

requests庫

Requests 唯一的一個非轉(zhuǎn)基因的 Python HTTP 庫檀何,人類可以安全享用蝇裤。
警告:非專業(yè)使用其他 HTTP 庫會導(dǎo)致危險的副作用廷支,包括:安全缺陷癥、冗余代碼癥栓辜、重新發(fā)明輪子癥恋拍、啃文檔癥、抑郁藕甩、頭疼施敢、甚至死亡。
Requests 允許你發(fā)送純天然狭莱,植物飼養(yǎng)的 HTTP/1.1 請求僵娃,無需手工勞動。你不需要手動為 URL 添加查詢字串贩毕,也不需要對 POST 數(shù)據(jù)進(jìn)行表單編碼悯许。Keep-alive 和 HTTP 連接池的功能是 100% 自動化的,一切動力都來自于根植在 Requests 內(nèi)部的 urllib3辉阶。

各種請求方式

requests里提供個各種請求方式

import requests
requests.post("http://httpbin.org/post")
requests.put("http://httpbin.org/put")
requests.delete("http://httpbin.org/delete")
requests.head("http://httpbin.org/get")
requests.options("http://httpbin.org/get")

基本GET請求

import requests
response = requests.get('http://httpbin.org/get')
print(response.text)

帶參數(shù)的GET請求

import requests

response = requests.get("http://httpbin.org/get?name=zhaofan&age=23")
print(response.text)
import requests
data = {
    "name":"zhaofan",
    "age":22
}
response = requests.get("http://httpbin.org/get",params=data)
print(response.url)
print(response.text)

上述兩種的結(jié)果是相同的先壕,通過params參數(shù)傳遞一個字典內(nèi)容,從而直接構(gòu)造url
注意:第二種方式通過字典的方式的時候谆甜,如果字典中的參數(shù)為None則不會添加到url上
基本POST請求

通過在發(fā)送post請求時添加一個data參數(shù)垃僚,這個data參數(shù)可以通過字典構(gòu)造成,這樣
對于發(fā)送post請求就非常方便

import requests

data = {
    "name":"zhaofan",
    "age":23
}
response = requests.post("http://httpbin.org/post",data=data)
print(response.text)

同樣的在發(fā)送post請求的時候也可以和發(fā)送get請求一樣通過headers參數(shù)傳遞一個字典類型的數(shù)據(jù)

響應(yīng)
我們可以通過response獲得很多屬性规辱,例子如下

import requests

response = requests.get("http://www.baidu.com")
print(type(response.status_code),response.status_code)
print(type(response.headers),response.headers)
print(type(response.cookies),response.cookies)
print(type(response.url),response.url)
print(type(response.history),response.history)

獲取cookie

import requests

response = requests.get("http://www.baidu.com")
print(response.cookies)

for key,value in response.cookies.items():
    print(key+"="+value)

會話維持

cookie的一個作用就是可以用于模擬登陸谆棺,做會話維持

import requests
s = requests.Session()
s.get("http://httpbin.org/cookies/set/number/123456")
response = s.get("http://httpbin.org/cookies")
print(response.text)

證書驗證

現(xiàn)在的很多網(wǎng)站都是https的方式訪問,所以這個時候就涉及到證書的問題

import requests

response = requests.get("https:/www.12306.cn")
print(response.status_code)

import requests
from requests.packages import urllib3
urllib3.disable_warnings()
response = requests.get("https://www.12306.cn",verify=False)
print(response.status_code)

代理設(shè)置

import requests

proxies= {
    "http":"http://127.0.0.1:9999",
    "https":"http://127.0.0.1:8888"
}
response  = requests.get("https://www.baidu.com",proxies=proxies)
print(response.text)

超時設(shè)置

通過timeout參數(shù)可以設(shè)置超時的時間

認(rèn)證設(shè)置

如果碰到需要認(rèn)證的網(wǎng)站可以通過requests.auth模塊實現(xiàn)

import requests

from requests.auth import HTTPBasicAuth

response = requests.get("http://120.27.34.24:9001/",auth=HTTPBasicAuth("user","123"))
print(response.status_code)

import requests

response = requests.get("http://120.27.34.24:9001/",auth=("user","123"))
print(response.status_code)

xpath解析Dom樹

XPath 是一門在 XML 文檔中查找信息的語言罕袋。
XPath 是 XSLT 中的主要元素改淑。
XQuery 和 XPointer 均構(gòu)建于 XPath 表達(dá)式之上
XPath總體來說功能很強(qiáng)大,而且查找效率別正則表達(dá)式要好很多浴讯,這里我們只用到一部分常用功能朵夏。
選取節(jié)點
XPath 使用路徑表達(dá)式在 XML 文檔中選取節(jié)點。節(jié)點是通過沿著路徑或者 step 來選取的榆纽。 下面列出了最有用的路徑表達(dá)式:


image.png

在下面的表格中仰猖,我們已列出了一些路徑表達(dá)式以及表達(dá)式的結(jié)果:


image.png

謂語(Predicates)
謂語用來查找某個特定的節(jié)點或者包含某個指定的值的節(jié)點。
謂語被嵌在方括號中奈籽。
在下面的表格中饥侵,我們列出了帶有謂語的一些路徑表達(dá)式,以及表達(dá)式的結(jié)果:
image.png

選取未知節(jié)點
XPath 通配符可用來選取未知的 XML 元素衣屏。
image.png

在下面的表格中躏升,我們列出了一些路徑表達(dá)式,以及這些表達(dá)式的結(jié)果:


image.png

選取若干路徑
通過在路徑表達(dá)式中使用"|"運算符狼忱,您可以選取若干個路徑煮甥。
在下面的表格中盗温,我們列出了一些路徑表達(dá)式藕赞,以及這些表達(dá)式的結(jié)果:
image.png

模擬GitHub登錄獲取個人信息

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Created by master on  2018/7/2 16:21.


import requests
import re
from lxml import etree

user_headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh,en;q=0.9,zh-CN;q=0.8',
}


# html文檔下載模塊
def download_html(user, pwd):
    login_url = 'https://github.com/login'
    # 使用session自動處理cookies
    session = requests.Session()
    # 獲取authenticity_token
    response = session.get(login_url, headers=user_headers, verify=False)
    pattern = re.compile(r'<input type="hidden" name="authenticity_token" value="(.*)" />')
    authenticity_token = pattern.findall(response.text)[0]
    # 登錄參數(shù)
    login_data = {
        'commit': 'Sign in',
        'utf8': '?',
        'authenticity_token': authenticity_token, 'login': user,
        'password': pwd
    }

    # 登錄
    session_url = 'https://github.com/session'
    response = session.post(session_url, headers=user_headers, data=login_data, verify=False)
    pattern = re.compile(r'Incorrect username or password')
    if pattern.findall(response.text):  # 密碼錯誤
        print("賬號或密碼錯誤成肘!")
        return
    else:
        # 獲取user_id
        pattern = re.compile(r'Signed in as <strong class="css-truncate-target">(.*)</strong>')
        user_id = pattern.findall(response.text)[0]
        # 請求個人信息頁面
        response = session.get("https://github.com/" + user_id, headers=user_headers, verify=False)

        return etree.HTML(response.text)


# 信息解析模塊
def parse_html(html):
    if not html:
        return
    your_avatar = html.xpath("http://img[@class='avatar width-full rounded-2']/@src")[0]
    your_nickname = html.xpath("http://span[@class='p-name vcard-fullname d-block overflow-hidden']/text()")[0]
    your_user_id = html.xpath("http://span[@class='p-nickname vcard-username d-block']/text()")[0]
    your_repositories = html.xpath("http://a[@class='UnderlineNav-item '][@title='Repositories']/span/text()")[0]
    your_stars = html.xpath("http://a[@class='UnderlineNav-item '][@title='Stars']/span/text()")[0]
    your_follows = html.xpath("http://a[@class='UnderlineNav-item '][@title='Followers']/span/text()")[0]
    your_following = html.xpath("http://a[@class='UnderlineNav-item '][@title='Following']/span/text()")[0]

    print("your avatar url: %s" % your_avatar)
    print("your nick name: %s" % trim(your_nickname))
    print("your user id: %s" % trim(your_user_id))
    print("your repositories count: %s" % trim(your_repositories))
    print("your starts count: %s" % trim(your_stars))
    print("your follows count: %s" % trim(your_follows))
    print("your fans count: %s" % trim(your_following))


# 去掉空格和換行
def trim(txt):
    return txt.strip().replace("\n", "")


if __name__ == '__main__':
    username = input("請輸入您的GitHub賬號:")
    password = input("請輸入您的GitHub密碼:")

    html_doc = download_html(username, password)
    parse_html(html_doc)

輸出

請輸入您的GitHub賬號:**********
請輸入您的GitHub密碼:**********

your avatar url: https://avatars2.githubusercontent.com/u/11495586?s=460&v=4
your nick name: lxy
your user id: lxygithub
your repositories count: 29
your starts count: 60
your follows count: 2
your fans count: 6
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市斧蜕,隨后出現(xiàn)的幾起案子双霍,更是在濱河造成了極大的恐慌,老刑警劉巖批销,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洒闸,死亡現(xiàn)場離奇詭異,居然都是意外死亡均芽,警方通過查閱死者的電腦和手機(jī)丘逸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掀宋,“玉大人深纲,你說我怎么就攤上這事【⒚睿” “怎么了湃鹊?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長镣奋。 經(jīng)常有香客問我币呵,道長,這世上最難降的妖魔是什么侨颈? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任余赢,我火速辦了婚禮,結(jié)果婚禮上哈垢,老公的妹妹穿的比我還像新娘妻柒。我一直安慰自己,他們只是感情好温赔,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布蛤奢。 她就那樣靜靜地躺著,像睡著了一般陶贼。 火紅的嫁衣襯著肌膚如雪啤贩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天拜秧,我揣著相機(jī)與錄音痹屹,去河邊找鬼。 笑死枉氮,一個胖子當(dāng)著我的面吹牛志衍,可吹牛的內(nèi)容都是我干的暖庄。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼楼肪,長吁一口氣:“原來是場噩夢啊……” “哼培廓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起春叫,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤肩钠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后暂殖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體价匠,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年呛每,在試婚紗的時候發(fā)現(xiàn)自己被綠了踩窖。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡晨横,死狀恐怖洋腮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情颓遏,我是刑警寧澤徐矩,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站叁幢,受9級特大地震影響滤灯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜曼玩,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一鳞骤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧黍判,春花似錦豫尽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至贬墩,卻和暖如春榴嗅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背陶舞。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工嗽测, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肿孵。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓唠粥,卻偏偏與公主長得像疏魏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晤愧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 聲明:本文講解的實戰(zhàn)內(nèi)容大莫,均僅用于學(xué)習(xí)交流,請勿用于任何商業(yè)用途养涮! 一葵硕、前言 強(qiáng)烈建議:請在電腦的陪同下,閱讀本文...
    Bruce_Szh閱讀 12,682評論 6 28
  • 1. 概述 本文主要介紹網(wǎng)絡(luò)爬蟲贯吓,采用的實現(xiàn)語言為Python,目的在于闡述網(wǎng)絡(luò)爬蟲的原理和實現(xiàn)蜀变,并且對目前常見的...
    Lemon_Home閱讀 2,731評論 0 21
  • scrapy學(xué)習(xí)筆記(有示例版) 我的博客 scrapy學(xué)習(xí)筆記1.使用scrapy1.1創(chuàng)建工程1.2創(chuàng)建爬蟲模...
    陳思煜閱讀 12,668評論 4 46
  • 那是一片碧綠的草地 我躺在它的懷里 夜幕拉下來 依舊可以看到那些五彩的花兒 我的眼前 是閃閃發(fā)光光的寶石 在黑色的...
    余憐鳥閱讀 195評論 0 1
  • 有一種精神叫做契約精神悄谐。我們能走到今天,從最早幾個人走到一起库北,說好了賺錢怎么分就一直在堅持;我們對所有員工的承諾爬舰、...
    新吶喊閱讀 6,454評論 13 20