欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python使用Srapy框架爬蟲模擬登陸并抓取知乎內(nèi)容

 更新時(shí)間:2016年07月02日 18:35:48   作者:Andrew_liu  
這里我們來看如何通過Python使用Srapy框架爬蟲模擬登陸并抓取知乎內(nèi)容的實(shí)例,要實(shí)現(xiàn)持續(xù)的爬取需要利用到cookie的保存,我們首先還是來回顧一下cookie的相關(guān)知識(shí)點(diǎn):

一、Cookie原理
HTTP是無狀態(tài)的面向連接的協(xié)議, 為了保持連接狀態(tài), 引入了Cookie機(jī)制
Cookie是http消息頭中的一種屬性,包括:

  • Cookie名字(Name)Cookie的值(Value)
  • Cookie的過期時(shí)間(Expires/Max-Age)
  • Cookie作用路徑(Path)
  • Cookie所在域名(Domain),使用Cookie進(jìn)行安全連接(Secure)

前兩個(gè)參數(shù)是Cookie應(yīng)用的必要條件,另外,還包括Cookie大小(Size,不同瀏覽器對(duì)Cookie個(gè)數(shù)及大小限制是有差異的)。

二、模擬登陸
這次主要爬取的網(wǎng)站是知乎
爬取知乎就需要登陸的, 通過之前的python內(nèi)建庫, 可以很容易的實(shí)現(xiàn)表單提交。

現(xiàn)在就來看看如何通過Scrapy實(shí)現(xiàn)表單提交。

首先查看登陸時(shí)的表單結(jié)果, 依然像前面使用的技巧一樣, 故意輸錯(cuò)密碼, 方面抓到登陸的網(wǎng)頁頭部和表單(我使用的Chrome自帶的開發(fā)者工具中的Network功能)

201672182940777.png (702×170)

查看抓取到的表單可以發(fā)現(xiàn)有四個(gè)部分:

  • 郵箱和密碼就是個(gè)人登陸的郵箱和密碼
  • rememberme字段表示是否記住賬號(hào)
  • 第一個(gè)字段是_xsrf,猜測(cè)是一種驗(yàn)證機(jī)制
  • 現(xiàn)在只有_xsrf不知道, 猜想這個(gè)驗(yàn)證字段肯定會(huì)實(shí)現(xiàn)在請(qǐng)求網(wǎng)頁的時(shí)候發(fā)送過來, 那么我們查看當(dāng)前網(wǎng)頁的源碼(鼠標(biāo)右鍵然后查看網(wǎng)頁源代碼, 或者直接用快捷鍵)

201672183128262.png (1788×782)

發(fā)現(xiàn)我們的猜測(cè)是正確的

那么現(xiàn)在就可以來寫表單登陸功能了

def start_requests(self):
    return [Request("https://www.zhihu.com/login", callback = self.post_login)] #重寫了爬蟲類的方法, 實(shí)現(xiàn)了自定義請(qǐng)求, 運(yùn)行成功后會(huì)調(diào)用callback回調(diào)函數(shù)

  #FormRequeset
  def post_login(self, response):
    print 'Preparing login'
    #下面這句話用于抓取請(qǐng)求網(wǎng)頁后返回網(wǎng)頁中的_xsrf字段的文字, 用于成功提交表單
    xsrf = Selector(response).xpath('//input[@name="_xsrf"]/@value').extract()[0]
    print xsrf
    #FormRequeset.from_response是Scrapy提供的一個(gè)函數(shù), 用于post表單
    #登陸成功后, 會(huì)調(diào)用after_login回調(diào)函數(shù)
    return [FormRequest.from_response(response,  
              formdata = {
              '_xsrf': xsrf,
              'email': '123456',
              'password': '123456'
              },
              callback = self.after_login
              )]

其中主要的功能都在函數(shù)的注釋中說明
三、Cookie的保存
為了能使用同一個(gè)狀態(tài)持續(xù)的爬取網(wǎng)站, 就需要保存cookie, 使用cookie保存狀態(tài), Scrapy提供了cookie處理的中間件, 可以直接拿來使用

CookiesMiddleware:

這個(gè)cookie中間件保存追蹤web服務(wù)器發(fā)出的cookie, 并將這個(gè)cookie在接來下的請(qǐng)求的時(shí)候進(jìn)行發(fā)送
Scrapy官方的文檔中給出了下面的代碼范例 :

for i, url in enumerate(urls):
  yield scrapy.Request("http://www.example.com", meta={'cookiejar': i},
    callback=self.parse_page)

def parse_page(self, response):
  # do some processing
  return scrapy.Request("http://www.example.com/otherpage",
    meta={'cookiejar': response.meta['cookiejar']},
    callback=self.parse_other_page)

那么可以對(duì)我們的爬蟲類中方法進(jìn)行修改, 使其追蹤cookie

  #重寫了爬蟲類的方法, 實(shí)現(xiàn)了自定義請(qǐng)求, 運(yùn)行成功后會(huì)調(diào)用callback回調(diào)函數(shù)
  def start_requests(self):
    return [Request("https://www.zhihu.com/login", meta = {'cookiejar' : 1}, callback = self.post_login)] #添加了meta

  #FormRequeset出問題了
  def post_login(self, response):
    print 'Preparing login'
    #下面這句話用于抓取請(qǐng)求網(wǎng)頁后返回網(wǎng)頁中的_xsrf字段的文字, 用于成功提交表單
    xsrf = Selector(response).xpath('//input[@name="_xsrf"]/@value').extract()[0]
    print xsrf
    #FormRequeset.from_response是Scrapy提供的一個(gè)函數(shù), 用于post表單
    #登陸成功后, 會(huì)調(diào)用after_login回調(diào)函數(shù)
    return [FormRequest.from_response(response,  #"http://www.zhihu.com/login",
              meta = {'cookiejar' : response.meta['cookiejar']}, #注意這里cookie的獲取
              headers = self.headers,
              formdata = {
              '_xsrf': xsrf,
              'email': '123456',
              'password': '123456'
              },
              callback = self.after_login,
              dont_filter = True
              )]

四、偽裝頭部
有時(shí)候登陸網(wǎng)站需要進(jìn)行頭部偽裝, 比如增加防盜鏈的頭部, 還有模擬服務(wù)器登陸

201672183151347.png (2136×604)

為了保險(xiǎn), 我們可以在頭部中填充更多的字段, 如下

  headers = {
  "Accept": "*/*",
  "Accept-Encoding": "gzip,deflate",
  "Accept-Language": "en-US,en;q=0.8,zh-TW;q=0.6,zh;q=0.4",
  "Connection": "keep-alive",
  "Content-Type":" application/x-www-form-urlencoded; charset=UTF-8",
  "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",
  "Referer": "http://www.zhihu.com/"
  }

在scrapy中Request和FormRequest初始化的時(shí)候都有一個(gè)headers字段, 可以自定義頭部, 這樣我們可以添加headers字段

形成最終版的登陸函數(shù)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.selector import Selector
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.http import Request, FormRequest
from zhihu.items import ZhihuItem



class ZhihuSipder(CrawlSpider) :
  name = "zhihu"
  allowed_domains = ["www.zhihu.com"]
  start_urls = [
    "http://www.zhihu.com"
  ]
  rules = (
    Rule(SgmlLinkExtractor(allow = ('/question/\d+#.*?', )), callback = 'parse_page', follow = True),
    Rule(SgmlLinkExtractor(allow = ('/question/\d+', )), callback = 'parse_page', follow = True),
  )
  headers = {
  "Accept": "*/*",
  "Accept-Encoding": "gzip,deflate",
  "Accept-Language": "en-US,en;q=0.8,zh-TW;q=0.6,zh;q=0.4",
  "Connection": "keep-alive",
  "Content-Type":" application/x-www-form-urlencoded; charset=UTF-8",
  "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",
  "Referer": "http://www.zhihu.com/"
  }

  #重寫了爬蟲類的方法, 實(shí)現(xiàn)了自定義請(qǐng)求, 運(yùn)行成功后會(huì)調(diào)用callback回調(diào)函數(shù)
  def start_requests(self):
    return [Request("https://www.zhihu.com/login", meta = {'cookiejar' : 1}, callback = self.post_login)]

  #FormRequeset出問題了
  def post_login(self, response):
    print 'Preparing login'
    #下面這句話用于抓取請(qǐng)求網(wǎng)頁后返回網(wǎng)頁中的_xsrf字段的文字, 用于成功提交表單
    xsrf = Selector(response).xpath('//input[@name="_xsrf"]/@value').extract()[0]
    print xsrf
    #FormRequeset.from_response是Scrapy提供的一個(gè)函數(shù), 用于post表單
    #登陸成功后, 會(huì)調(diào)用after_login回調(diào)函數(shù)
    return [FormRequest.from_response(response,  #"http://www.zhihu.com/login",
              meta = {'cookiejar' : response.meta['cookiejar']},
              headers = self.headers, #注意此處的headers
              formdata = {
              '_xsrf': xsrf,
              'email': '1095511864@qq.com',
              'password': '123456'
              },
              callback = self.after_login,
              dont_filter = True
              )]

  def after_login(self, response) :
    for url in self.start_urls :
      yield self.make_requests_from_url(url)

  def parse_page(self, response):
    problem = Selector(response)
    item = ZhihuItem()
    item['url'] = response.url
    item['name'] = problem.xpath('//span[@class="name"]/text()').extract()
    print item['name']
    item['title'] = problem.xpath('//h2[@class="zm-item-title zm-editable-content"]/text()').extract()
    item['description'] = problem.xpath('//div[@class="zm-editable-content"]/text()').extract()
    item['answer']= problem.xpath('//div[@class=" zm-editable-content clearfix"]/text()').extract()
    return item

五、Item類和抓取間隔
完整的知乎爬蟲代碼鏈接

from scrapy.item import Item, Field


class ZhihuItem(Item):
  # define the fields for your item here like:
  # name = scrapy.Field()
  url = Field() #保存抓取問題的url
  title = Field() #抓取問題的標(biāo)題
  description = Field() #抓取問題的描述
  answer = Field() #抓取問題的答案
  name = Field() #個(gè)人用戶的名稱

設(shè)置抓取間隔, 訪問由于爬蟲的過快抓取, 引發(fā)網(wǎng)站的發(fā)爬蟲機(jī)制, 在setting.py中設(shè)置

BOT_NAME = 'zhihu'

SPIDER_MODULES = ['zhihu.spiders']
NEWSPIDER_MODULE = 'zhihu.spiders'
DOWNLOAD_DELAY = 0.25  #設(shè)置下載間隔為250ms

更多設(shè)置可以查看官方文檔

抓取結(jié)果(只是截取了其中很少一部分)

...
 'url': 'http://www.zhihu.com/question/20688855/answer/16577390'}
2014-12-19 23:24:15+0800 [zhihu] DEBUG: Crawled (200) <GET http://www.zhihu.com/question/20688855/answer/15861368> (referer: http://www.zhihu.com/question/20688855/answer/19231794)
[]
2014-12-19 23:24:15+0800 [zhihu] DEBUG: Scraped from <200 http://www.zhihu.com/question/20688855/answer/15861368>
  {'answer': [u'\u9009\u4f1a\u8ba1\u8fd9\u4e2a\u4e13\u4e1a\uff0c\u8003CPA\uff0c\u5165\u8d22\u52a1\u8fd9\u4e2a\u884c\u5f53\u3002\u8fd9\u4e00\u8def\u8d70\u4e0b\u6765\uff0c\u6211\u53ef\u4ee5\u5f88\u80af\u5b9a\u7684\u544a\u8bc9\u4f60\uff0c\u6211\u662f\u771f\u7684\u559c\u6b22\u8d22\u52a1\uff0c\u70ed\u7231\u8fd9\u4e2a\u884c\u4e1a\uff0c\u56e0\u6b64\u575a\u5b9a\u4e0d\u79fb\u5730\u5728\u8fd9\u4e2a\u884c\u4e1a\u4e2d\u8d70\u4e0b\u53bb\u3002',
        u'\u4e0d\u8fc7\u4f60\u8bf4\u6709\u4eba\u4ece\u5c0f\u5c31\u559c\u6b22\u8d22\u52a1\u5417\uff1f\u6211\u89c9\u5f97\u51e0\u4e4e\u6ca1\u6709\u5427\u3002\u8d22\u52a1\u7684\u9b45\u529b\u5728\u4e8e\u4f60\u771f\u6b63\u61c2\u5f97\u5b83\u4e4b\u540e\u3002',
        u'\u901a\u8fc7\u5b83\uff0c\u4f60\u53ef\u4ee5\u5b66\u4e60\u4efb\u4f55\u4e00\u79cd\u5546\u4e1a\u7684\u7ecf\u8425\u8fc7\u7a0b\uff0c\u4e86\u89e3\u5176\u7eb7\u7e41\u5916\u8868\u4e0b\u7684\u5b9e\u7269\u6d41\u3001\u73b0\u91d1\u6d41\uff0c\u751a\u81f3\u4f60\u53ef\u4ee5\u638c\u63e1\u5982\u4f55\u53bb\u7ecf\u8425\u8fd9\u79cd\u5546\u4e1a\u3002',
        u'\u5982\u679c\u5bf9\u4f1a\u8ba1\u7684\u8ba4\u8bc6\u4ec5\u4ec5\u505c\u7559\u5728\u505a\u5206\u5f55\u8fd9\u4e2a\u5c42\u9762\uff0c\u5f53\u7136\u4f1a\u89c9\u5f97\u67af\u71e5\u65e0\u5473\u3002\u5f53\u4f60\u5bf9\u5b83\u7684\u8ba4\u8bc6\u8fdb\u5165\u5230\u6df1\u5c42\u6b21\u7684\u65f6\u5019\uff0c\u4f60\u81ea\u7136\u5c31\u4f1a\u559c\u6b22\u4e0a\u5b83\u4e86\u3002\n\n\n'],
   'description': [u'\u672c\u4eba\u5b66\u4f1a\u8ba1\u6559\u80b2\u4e13\u4e1a\uff0c\u6df1\u611f\u5176\u67af\u71e5\u4e4f\u5473\u3002\n\u5f53\u521d\u662f\u51b2\u7740\u5e08\u8303\u4e13\u4e1a\u62a5\u7684\uff0c\u56e0\u4e3a\u68a6\u60f3\u662f\u6210\u4e3a\u4e00\u540d\u8001\u5e08\uff0c\u4f46\u662f\u611f\u89c9\u73b0\u5728\u666e\u901a\u521d\u9ad8\u4e2d\u8001\u5e08\u5df2\u7ecf\u8d8b\u4e8e\u9971\u548c\uff0c\u800c\u987a\u6bcd\u4eb2\u5927\u4eba\u7684\u610f\u9009\u4e86\u8fd9\u4e2a\u4e13\u4e1a\u3002\u6211\u559c\u6b22\u4e0a\u6559\u80b2\u5b66\u7684\u8bfe\uff0c\u5e76\u597d\u7814\u7a76\u5404\u79cd\u6559\u80b2\u5fc3\u7406\u5b66\u3002\u4f46\u4f1a\u8ba1\u8bfe\u4f3c\u4e4e\u662f\u4e3b\u6d41\u3001\u54ce\u3002\n\n\u4e00\u76f4\u4e0d\u559c\u6b22\u94b1\u4e0d\u94b1\u7684\u4e13\u4e1a\uff0c\u6240\u4ee5\u5f88\u597d\u5947\u5927\u5bb6\u9009\u4f1a\u8ba1\u4e13\u4e1a\u5230\u5e95\u662f\u51fa\u4e8e\u4ec0\u4e48\u76ee\u7684\u3002\n\n\u6bd4\u5982\u8bf4\u5b66\u4e2d\u6587\u7684\u4f1a\u8bf4\u4ece\u5c0f\u559c\u6b22\u770b\u4e66\uff0c\u4f1a\u6709\u4ece\u5c0f\u559c\u6b22\u4f1a\u8ba1\u501f\u554a\u8d37\u554a\u7684\u7684\u4eba\u5417\uff1f'],
   'name': [],
   'title': [u'\n\n', u'\n\n'],
   'url': 'http://www.zhihu.com/question/20688855/answer/15861368'}
...

六、存在問題

  • Rule設(shè)計(jì)不能實(shí)現(xiàn)全網(wǎng)站抓取, 只是設(shè)置了簡單的問題的抓取
  • Xpath設(shè)置不嚴(yán)謹(jǐn), 需要重新思考
  • Unicode編碼應(yīng)該轉(zhuǎn)換成UTF-8

相關(guān)文章

  • python實(shí)現(xiàn)ModBusTCP協(xié)議的client功能

    python實(shí)現(xiàn)ModBusTCP協(xié)議的client功能

    Modbus TCP 是一種基于 TCP/IP 協(xié)議棧的 Modbus 通信協(xié)議,它用于在工業(yè)自動(dòng)化系統(tǒng)中進(jìn)行設(shè)備之間的通信,只要通過pymodbus或pyModbusTCP任意模塊就可以實(shí)現(xiàn),本文采用pymodbus,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • python 列表轉(zhuǎn)為字典的兩個(gè)小方法(小結(jié))

    python 列表轉(zhuǎn)為字典的兩個(gè)小方法(小結(jié))

    這篇文章主要介紹了python 列表轉(zhuǎn)為字典的兩個(gè)小方法(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • django中send_mail功能實(shí)現(xiàn)詳解

    django中send_mail功能實(shí)現(xiàn)詳解

    這篇文章主要給大家介紹了關(guān)于django中send_mail功能實(shí)現(xiàn)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-02-02
  • python基于socket函數(shù)實(shí)現(xiàn)端口掃描

    python基于socket函數(shù)實(shí)現(xiàn)端口掃描

    這篇文章主要為大家詳細(xì)介紹了python基于socket函數(shù)實(shí)現(xiàn)端口掃描,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • pycharm的console輸入實(shí)現(xiàn)換行的方法

    pycharm的console輸入實(shí)現(xiàn)換行的方法

    今天小編就為大家分享一篇pycharm的console輸入實(shí)現(xiàn)換行的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • python斐波那契數(shù)列的計(jì)算方法

    python斐波那契數(shù)列的計(jì)算方法

    這篇文章主要為大家詳細(xì)介紹了python斐波那契數(shù)列的計(jì)算方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • Python實(shí)現(xiàn)在Excel文件中寫入圖表

    Python實(shí)現(xiàn)在Excel文件中寫入圖表

    這篇文章主要為大家介紹了如何利用Python語言實(shí)現(xiàn)在Excel文件中寫入一個(gè)比較簡單的圖表,文中的實(shí)現(xiàn)方法講解詳細(xì),快動(dòng)手嘗試一下吧
    2022-05-05
  • 如何將python代碼生成API接口

    如何將python代碼生成API接口

    這篇文章主要介紹了如何將python代碼生成API接口,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • python提取log文件內(nèi)容并畫出圖表

    python提取log文件內(nèi)容并畫出圖表

    這篇文章主要介紹了python提取log文件內(nèi)容并畫出圖表,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • 在Python中利用Into包整潔地進(jìn)行數(shù)據(jù)遷移的教程

    在Python中利用Into包整潔地進(jìn)行數(shù)據(jù)遷移的教程

    這篇文章主要介紹了在Python中如何利用Into包整潔地進(jìn)行數(shù)據(jù)遷移,在數(shù)據(jù)格式的任意兩個(gè)格式之間高效地遷移數(shù)據(jù),需要的朋友可以參考下
    2015-03-03

最新評(píng)論