天天看點

Python爬蟲實作--微網誌模拟登陸--涉及到的知識點,python包,實作代碼詳解。

之前寫過一篇關于爬蟲的文章,其中提到了用python requests包請求網頁,并用beautifulsoup解析。

https://blog.csdn.net/qq_40589051/article/details/90579064

當時那篇文章中的網頁都是不需要登陸的,而且由于趕項目是以學的那叫一個囫囵吞棗。請求,協定之類的知識點都沒有怎麼搞清楚,後來我發現網上的大佬們對于模拟登陸的方法頗有心得,是以我最近小小的研究了一下下。自己平時也很少研究爬蟲,是以有什麼錯請多多包涵~

這篇文章着重介紹的是如何模拟登陸微網誌,是以解析網頁源代碼的代碼就沒有放上來啦。

-------------------目錄---------------------

1.cookie和headers,究竟是什麼?如何檢視?謎一樣的HTTP協定!

2.微網誌爬蟲的三種實作方法(理論)

3.微網誌模拟登陸實作代碼詳解(實戰)

4 http協定中post和get請求的不同

5 python各種爬蟲包大起底!urllib、urllib2、requests。

包教包會诶~~~童叟無欺!

正文:

1.cookie和headers,究竟是什麼?如何檢視?謎一樣的HTTP協定

我還是個學通信的.....今天打死都想不起這些知識點,簡直慚愧......

我們在做爬蟲的時候,其實是在模拟浏覽器(使用者)的行為,去爬取所需要的資訊。

簡單來說,爬蟲得模拟我們正常使用浏覽器進網站的過程,首先是給網站一個請求,網站接受到請求之後,會發回一個響應。

這個請求和響應要按照一定的格式來建構,格式亂七八糟的當然不行,是以為了友善大家上網,專門為通路網際網路所設定的HTTP協定誕生啦!

HTTP協定是Hyper Text Transfer Protocol(超文本傳輸協定)的縮寫,是用于從網際網路(WWW:World Wide Web )伺服器傳輸超文本到本地浏覽器的傳送協定,其基于TCP/IP通信協定來傳遞資料(HTML 檔案, 圖檔檔案, 查詢結果等)。浏覽器作為HTTP用戶端通過URL向HTTP服務端即WEB伺服器發送所有請求。Web伺服器根據接收到的請求後,向用戶端發送響應資訊。

HTTP協定請求消息有四個部分:請求行(request line)、請求頭部(header)、空行和請求資料。

這裡就不細講了,主要将爬蟲需要用到的headers。

headers(請求頭部)就是HTTP請求和響應的核心部分,它記錄了用戶端浏覽器、請求頁面、伺服器等相關資訊。在寫爬蟲的過程中,獲得headers的資訊是非常重要的!

我使用的是谷歌浏覽器,打開一個頁面,按下f12,進入network,随便在name下點選一個動态,你就可以看見響應和請求的heders了。這個user-agent就是爬蟲所需要的模拟浏覽器的必要僞裝之一。User-Agent會告訴網站伺服器,通路者是通過什麼工具來請求的,如果是爬蟲請求,一般會拒絕,如果是使用者浏覽器,就會應答。是以我們的程式裡面得使用這個來表明自己不是爬蟲。

Python爬蟲實作--微網誌模拟登陸--涉及到的知識點,python包,實作代碼詳解。

headers講完了,那cookie又是個什麼呢?

你的小餅幹是存儲在本地端上的資料,包含了通路使用者的基本資訊,比如使用者名、計算機名字、使用的浏覽器名字和曾經通路的網站。它被儲存在本地浏覽器目錄下。可以讓網站辨識你的身份,進行會話跟蹤,因為涉及隐私,是以一般是加密的。

cookie應用點在于判斷注冊使用者是否登入,此時會彈出提示,是否下一次進同樣網站時自動登入;購物車,使用者在一個網站的不同頁面中選擇的不同商品的資訊,也被儲存在cookie中,友善最後結賬。

cookies的擷取是按control+shift+j,輸入document.cookie後回車得到的一大串字元,每個網站對應一個,涉及隐私是以一定要保護好哦~

獲得這兩大模拟浏覽器的利器之後,再來看看如何模拟登陸。

2.微網誌爬蟲的三種實作方法(理論)

1 直接先在浏覽器上先登陸,然後再調用微網誌上的api,擷取需要的文本。

2 直接填入cookies,user-agent等資訊,簡單粗暴。

3 使用post請求登陸,把使用者名,密碼還有cookie儲存下來模拟登陸。 

3.微網誌模拟登陸實作代碼詳解

第一個方法就不用介紹了吧~偷懶的方法。咱們直接從第二個開始。

import urllib.request

headers = {'cookie':'你的cookie',
'User-Agent':'你的user-agent'}

url = 'https://m.weibo.cn/detail/4400540303485380'

response = urllib.request.Request(url,headers=headers)
data=urllib.request.urlopen(response).read().decode('utf-8','ignore')
print(data)
           

cookie是你登陸微網誌頁面之後查到的cookie,user-agent也在開發者模式中得到,這樣我們就可以建構headers!再使用urllib去擷取網頁中的内容你就OK啦!

這個方法簡單粗暴,缺點是不能适用于大規模的爬取,cookie還會過期(一天就過期了),是以還是得使用第三種方法!

使用post請求登陸,把使用者名,密碼還有cookie儲存下來模拟登陸。 

這個我看了網上兩個很好的回答,主要是要自己能了解這段代碼的含義:

http://lovenight.github.io/2015/11/23/Python-%E6%A8%A1%E6%8B%9F%E7%99%BB%E5%BD%95%E6%96%B0%E6%B5%AA%E5%BE%AE%E5%8D%9A/

https://www.douban.com/note/201767245/?start=100#comments

使用者名和密碼都是通過base64加密的,是以需要解碼。

post請求是使用的request body,使用httpfox可以看到滴~

這是大佬寫的代碼。

import requests
import json
import base64

def login(username, password):
    username = base64.b64encode(username.encode('utf-8')).decode('utf-8')
    postData = {
        "entry": "sso",
        "gateway": "1",
        "from": "null",
        "savestate": "30",
        "useticket": "0",
        "pagerefer": "",
        "vsnf": "1",
        "su": username,
        "service": "sso",
        "sp": password,
        "sr": "1440*900",
        "encoding": "UTF-8",
        "cdult": "3",
        "domain": "sina.com.cn",
        "prelt": "0",
        "returntype": "TEXT",
    }
    loginURL = r'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15)'
    session = requests.Session()
    res = session.post(loginURL, data = postData)
    jsonStr = res.content.decode('gbk')
    info = json.loads(jsonStr)
    if info["retcode"] == "0":
        print("登入成功")
        # 把cookies添加到headers中,必須寫這一步,否則後面調用API失敗
        cookies = session.cookies.get_dict()
        cookies = [key + "=" + value for key, value in cookies.items()]
        cookies = "; ".join(cookies)
        session.headers["cookie"] = cookies
    else:
        print("登入失敗,原因: %s" % info["reason"])
    return session

if __name__ == '__main__':
    session = login('你的使用者名', '你的密碼')
           

4 http中post和get請求的不同

  • GET在浏覽器回退時是無害的,而POST會再次送出請求。
  • GET産生的URL位址可以被Bookmark,而POST不可以。
  • GET請求會被浏覽器主動cache,而POST不會,除非手動設定。
  • GET請求隻能進行url編碼,而POST支援多種編碼方式。
  • GET請求參數會被完整保留在浏覽器曆史記錄裡,而POST中的參數不會被保留。
  • GET請求在URL中傳送的參數是有長度限制的,而POST麼有。
  • 對參數的資料類型,GET隻接受ASCII字元,而POST沒有限制。
  • GET比POST更不安全,因為參數直接暴露在URL上,是以不能用來傳遞敏感資訊。
  • GET參數通過URL傳遞,POST放在Request body中。

5 python各種爬蟲包大起底!

python中網絡子產品中的包常見的有urllib123代,requests包。

request快速使用指南在此:https://2.python-requests.org//zh_CN/latest/#

urllib

class urllib.request.

urlopen

(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)¶

打開統一資源定位位址 url,可以是一個字元串或一個 

Request

 對象。

class 

urllib.request.

Request

(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)¶

This class is an abstraction of a URL request.

url 應該是是一個含有一個有效的統一資源定位位址的字元串。

之前的代碼就是用到的這個包,是不是很友善呀!

urllib2

從官網摘下來的我用到過的一些方法,其實和urllib差別不大。

urllib2.

urlopen

(url[, data[, timeout[, cafile[, capath[, cadefault[, context]]]]])

Open the URL url, which can be either a string or a 

Request

 object.

This function returns a file-like object with three additional methods:

  • geturl()

     — return the URL of the resource retrieved, commonly used to determine if a redirect was followed
  • info()

     — return the meta-information of the page, such as headers, in the form of an 

    mimetools.Message

     instance (see Quick Reference to HTTP Headers)
  • getcode()

     — return the HTTP status code of the response.

class 

urllib2.

Request

(url[, data][, headers][, origin_req_host][, unverifiable])

This class is an abstraction of a URL request.

The following methods describe all of 

Request

’s public interface, and so all must be overridden in subclasses.

Request.

add_data

(data)

Set the 

Request

 data to data. This is ignored by all handlers except HTTP handlers — and there it should be a byte string, and will change the request to be 

POST

rather than 

GET

.

Request.

get_method

()

Return a string indicating the HTTP request method. This is only meaningful for HTTP requests, and currently always returns 

'GET'

 or 

'POST'

.

Request.

has_data

()

Return whether the instance has a non-

None

 data.

Request.

get_data

()

Return the instance’s data.

Request.

add_header

(key, val)

Add another header to the request. Headers are currently ignored by all handlers except HTTP handlers, where they are added to the list of headers sent to the server. Note that there cannot be more than one header with the same name, and later calls will overwrite previous calls in case the key collides. Currently, this is no loss of HTTP functionality, since all headers which have meaning when used more than once have a (header-specific) way of gaining the same functionality using only one header.

Request.

add_unredirected_header

(key, header)

Add a header that will not be added to a redirected request.

New in version 2.4.

Request.

has_header

(header)

Return whether the instance has the named header (checks both regular and unredirected).

New in version 2.4.

Request.

get_full_url

()

Return the URL given in the constructor.

Request.

get_type

()

Return the type of the URL — also known as the scheme.

Request.

get_host

()

Return the host to which a connection will be made.

Request.

get_header

(header_name, default=None)

Return the value of the given header. If the header is not present, return the default value.

requests

上面那位大佬就是使用的request進行的微網誌的模拟登陸,而且使用的是post請求,還使用了會話(session)~詳細的都在這個官網的代碼中~

https://2.python-requests.org//zh_CN/latest/user/quickstart.html#id2

今天先寫到這裡吧,才研究兩天,感覺隻學到了一點皮毛呀,不過現在可以小批量的爬取微網誌等需要登入的網站的資訊啦,開心~