Cookie 是在 HTTP 協議下,服務器或腳本能夠維護客戶工做站上信息的一種方式。Cookie 是由 Web 服務器保存在用戶瀏覽器(客戶端)上的小文本文件,它能夠包含有關用戶的信息。不管什麼時候用戶連接到服務器,Web 站點均可以訪問 Cookie 信息cookie須要我的用戶登陸網站。
場景需求:獲取用戶我的主頁二級頁面的頁面數據。html
要登陸網站,所以必須發送post請求,如何實現發送post請求?
場景需求:百度翻譯中指定詞條對應的翻譯結果進行獲取。python
爬蟲文件中的爬蟲類繼承到了Spider父類中的start_requests(self)這個方法,該方法就能夠對start_urls列表中的url發起請求。
該方法默認的實現,是對起始的url發起get請求,若是想發起post請求,則須要子類重寫該方法。web
import scrapy class PostdemoSpider(scrapy.Spider): name = 'postDemo' # allowed_domains = ['www.baidu.com'] start_urls = ['https://fanyi.baidu.com/sug'] # 經過抓包找到post請求地址 def start_requests(self): """重寫的父類方法:該方法能夠對star_urls列表中的元素進行get請求發送""" for url in self.start_urls: # Request方法默認發送get請求,配置method參數賦值爲'post' yield scrapy.Request(url=url, callback=self.parse, method='post') def parse(self, response): pass
import scrapy class PostdemoSpider(scrapy.Spider): name = 'postDemo' # allowed_domains = ['www.baidu.com'] start_urls = ['https://fanyi.baidu.com/sug'] # 經過抓包找到post請求地址 def start_requests(self): """重寫的父類方法:該方法能夠對star_urls列表中的元素進行get請求發送""" print("start_requests()被調用") data = { 'kw': 'dog', # post請求參數 } for url in self.start_urls: # FormRequest()能夠發送post請求 # formdata表示請求參數對應的字典 yield scrapy.FormRequest(url=url, formdata=data, callback=self.parse) def parse(self, response): print(response.text)
# Crawl responsibly by identifying yourself (and your website) on the user-agent USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36' # 假裝請求載體身份 # Obey robots.txt rules ROBOTSTXT_OBEY = False # 不聽從門戶網站robots協議,避免某些信息爬取不到
# 建立項目和應用(後面的項目將再也不描述) $ scrapy startproject postPro $ cd postPro/ $ scrapy genspider postDemo www.baidu.com # 執行爬蟲命令 $ scrapy crawl postDemo --nolog start_requests()被調用 {"errno":0,"data":[{"k":"dog","v":"n. \u72d7; \u8e69\u811a\u8d27; \u4e11\u5973\u4eba; \u5351\u9119\u5c0f\u4eba; v. \u56f0\u6270; \u8ddf\u8e2a;"},{"k":"dogs","v":"n. \u516c\u72d7( dog\u7684\u540d\u8bcd\u590d\u6570 ); \uff08\u5c24\u7528\u4e8e\u5f62\u5bb9\u8bcd\u540e\uff09\u5bb6\u4f19; [\u673a\u68b0\u5b66]\u5939\u5934; \u4e0d\u53d7\u6b22\u8fce\u7684\u4eba;"},{"k":"doge","v":"n. \u5171\u548c\u56fd\u603b\u7763;"},{"k":"doggy","v":"n. \u5c0f\u72ac\uff0c\u5c0f\u72d7; adj. \u50cf\u72d7\u4e00\u6837\u7684;"},{"k":"doggie","v":"n. \u5c0f\u72d7\uff0c\u72d7\uff0c\u6c6a\u6c6a;"}]}
知道post請求後,來實現最開始的場景需求:獲取用戶我的主頁二級頁面的頁面數據。
新建項目doubanPro,這裏沒有在管道中處理,簡化操做直接在爬蟲文件中持久化數據保存在文件中,爬蟲文件douban.py以下所示:瀏覽器
import scrapy class DoubanSpider(scrapy.Spider): name = 'douban' allowed_domains = ['www.douban.com'] start_urls = ['https://www.douban.com/accounts/login'] def start_requests(self): """重寫父類方法""" # 將請求參數封裝到字典 data = { 'source': 'index_nav', 'form_email': '18xxxxxxx0', 'form_password': 'hxxxxxxx' } for url in self.start_urls: yield scrapy.FormRequest(url=url, formdata=data, callback=self.parse) def parseBySecondPage(self, response): """針對我的主頁頁面數據進行解析操做""" fp = open('second.html', 'w', encoding='utf-8') fp.write(response.text) # 能夠對當前用戶的我的主頁數據進行指定解析操做 # 若是服務器端能夠給咱們的請求返回一個cookie,第二次使用請求對象發起請求時,cookie就會自動攜帶到請求中 def parse(self, response): # 對登陸成功後的頁面數據進行存儲 # 這裏沒有在管道中處理,簡化操做直接保存在文件中 fp = open('main.html', 'w', encoding='utf-8') fp.write(response.text) # 獲取當前用戶的我的主頁 url = 'https://www.douban.com/people/186757832/' yield scrapy.Request(url=url, callback=self.parseBySecondPage)
def start_requests(self): """重寫父類方法""" # 將請求參數封裝到字典 data = { 'source': 'index_nav', 'form_email': '18xxxxxx0', 'form_password': 'hxxxxxxx' } for url in self.start_urls: yield scrapy.FormRequest(url=url, formdata=data, callback=self.parse)
def parseBySecondPage(self, response): """針對我的主頁頁面數據進行解析操做""" fp = open('second.html', 'w', encoding='utf-8') fp.write(response.text) def parse(self, response): # 對登陸成功後的頁面數據進行存儲 fp = open('main.html', 'w', encoding='utf-8') fp.write(response.text) # 獲取當前用戶的我的主頁 url = 'https://www.douban.com/people/186757832/' yield scrapy.Request(url=url, callback=self.parseBySecondPage)
若是服務器端能夠給咱們的請求返回一個cookie,第二次使用請求對象發起請求時,cookie就會自動攜帶到請求中。
查看mian.html和second.html文件,能夠發現兩次訪問結果相同,說明第二次發請求時攜帶了cookie。bash
新建proxyPro工程,經過爬蟲在百度搜索ip,獲取本地ip地址。服務器
import scrapy class ProxydemoSpider(scrapy.Spider): name = 'proxyDemo' # allowed_domains = ['www.baidu.com/s?wd=ip'] start_urls = ['http://www.baidu.com/s?wd=ip'] # 百度搜索到本地ip def parse(self, response): fp = open('proxy.html', 'w', encoding='utf-8') fp.write(response.text)
爬蟲文件編輯好後,修改settings.py文件,執行爬蟲:scrapy crawl proxyDemo --nolog;查看proxy.html內容以下所示:cookie
在項目當前的源文件middlewares.py中,能夠看到類:ProxyproDownloadMiddleware,這是封裝好的下載中間件。其中process_request方法最爲重要,負責處理請求。
在全網代理IP網站:http://www.goubanjia.com/,查找一條代理IP地址(39.137.69.10:8434)使用。dom
在middlewares.py中,自定義一個下載中間件的類,在類中實現process_request方法來處理中間件攔截到的請求。scrapy
from scrapy import signals class MyProxy(object): # 自定義下載中間件 def process_request(self, request, spider): # 將攔截的請求的請求ip更換 request.meta["proxy"] = "http://39.137.69.10:8434"
注意:ide
使用下載中間件,須要在配置文件中開啓下載中間件。
# Enable or disable downloader middlewares # See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html DOWNLOADER_MIDDLEWARES = { # 開啓下載中間件 # 'proxyPro.middlewares.ProxyproDownloaderMiddleware': 543, # 自定義下載中間件 'proxyPro.middlewares.MyProxy': 543, # 543爲優先級級別 }
$ scrapy crawl proxyDemo
查看得到的頁面信息: