本文中的知識點:
- 安裝scrapy
- scrapy的基礎教程
- scrapy使用代理
安裝scrapy
由於小哥的系統是win7,所以以下的演示是基於windows系統。linux系統的話,其實命令都一樣的,沒啥差,windows與linux都可以用。
pip install scrapy
安裝好後,先看下scrapy是否安裝上了,確認下,我的是Scrapy 1.8.0
scrapy version
好了,安裝很簡單。用scrapy創建個新項目吧。命令行下輸入,這裏注意,命令會在當前目錄下創建ts項目。
創建新項目
# 新建一個名爲ts的scrapy的項目
scrapy startproject ts
我是在桌面下創建的ts目錄,創建成功後給的提示截圖如下。
分析目錄文件
讓我們去目錄下看看都有些什麼,有個scrapy.cfg配置文件,ts目錄。
在進入ts目錄,看下有些什麼。嗯~~~ 主菜來了,這裏就是我們要寫的內容了。
- spiders目錄——爬蟲代碼放這裏
- items.py ——要抓取的字段
- middleware——中間件
- pipelines——管道文件
- settings——設置文件
先不用管這麼細,我們先跑起來。
代碼樣例
抓個百度首頁試試吧。
進入spiders目錄裏,創建個baidu的爬蟲,並且限制抓取域名的範圍。注意要在spiders的目錄下輸入以下命令
scrapy genspider baidu "baidu.com"
看到命令已經幫我們自動創建了爬蟲代碼,打開文件看下。
看下這裏的代碼,先導入scrapy,定義了一個BaiduSpider類,必須要繼承scrapy.Spider。這裏注意,裏面有3個必須的屬性(name,allowed_domains,start_urls)。
- name——爬蟲的名字,運行爬蟲的時候就看這個參數。
- allowed_domains——抓取的域名限制,這是我們剛纔在命令行輸入的。PS:抓百度,當然限制在百度內了,別抓到淘寶上去了,先不跨界
- start_urls——要抓取的url列表,類型list
- parse函數——抓取後的動作,可以自己定義
好的,既然都OK了,那我們去運行下,看看會發生什麼。
命令行下輸入,注意這裏的baidu就是爬蟲的name屬性。
scrapy crawl baidu
嘎嘎嘎,,,一大堆信息,看的是不是有點懵,說實話,我也是。這是正常信息,已經跑起來了。這些參數,大家隨意看一看吧,我先不解釋了。。。手動滑稽~~~哈哈哈,其實先不用看,一會我們在講。
代碼改造下,按照我們的預期來
還記得剛纔的parse函數麼,不過命令創建的是啥事都沒幹。自己定義下,讓它做點事,也好知道代碼是按照我們的預期去跑的。
# -*- coding: utf-8 -*-
import scrapy
class BaiduSpider(scrapy.Spider):
name = 'baidu'
allowed_domains = ['baidu.com']
start_urls = ['http://baidu.com/']
def parse(self, response):
# 打印下response返回的狀態碼
print(response.status)
在來運行下,還記得剛纔的運行命令嗎?不記得了?。。。行,我在說一遍,
scrapy crawl baidu
好的,讓我們看看會給什麼信息。嗯,,,有點問題,沒有打印response的狀態碼,看下日誌,這裏說的是爬蟲碰到了robots.txt,給Forbidden(禁止)了。MD,百度竟然不給我爬,百度自己的spider都在爬其他網站的,,,
這裏得解釋下爲什麼禁止了,這其實就是個爬蟲的哲學問題了,盜亦有道的道理,相信大家都聽說過,爬蟲也是,爬亦有道。robots.txt也就是robots協議,這個文件會告訴爬蟲,哪些能爬,哪些不能爬,爬蟲要遵守這個規則。畢竟是別人的網站嘛,,,
本文以教學爲主,旨在教大家使用scrapy框架,合理使用爬蟲,遵守互聯網規則是每一位互聯網人的責任。
好的,問題該怎麼解決?其實robots.txt也是可以解決的。這個時候settings.py就派上用場了。到我們之前的目錄下,找到settings.py文件。
打開看下,注意到ROBOTSTXT_OBEY = True ,這個就是遵守robots協議。
改成False,不遵守robots協議 ~~~嘿嘿嘿,別笑,,,我只是教大家學scrapy框架而已
再來運行下。看到這裏就已經打印出來了,返回200,成功抓取百度。
再來改造下
改造下parse函數,把抓取的數據保存到一個文件裏。畢竟之前的定義的parse動作是打印各種信息,都在看日誌,腦袋都大了,這次直接點,看文件好吧。
# -*- coding: utf-8 -*-
import scrapy
class BaiduSpider(scrapy.Spider):
name = 'baidu'
allowed_domains = ['baidu.com']
start_urls = ['http://baidu.com/']
def parse(self, response):
# 定義文件名 baidu.html
filename = 'baidu.html'
with open(filename, 'wb') as f:
f.write(response.body) #文件寫入response的body信息
好的,運行下試試。(PS:命令沒忘吧,忘了的往上翻翻),這裏注意我是在spiders目錄下運行的,baidu.html文件也會保存在當前目錄下。
看到了吧,文件出來了,直接雙擊打開看看,嗯,是百度首頁。
使用代理
準備工作,找個可靠的代理IP,剩下的跟着我的步驟走。
修改中間件配置
這裏就需要用到中間件了,找到文件middleware.py,打開看看文件。
這就是項目的中間件配置了。參數挺多,不過設置代理,我們只需要關注幾個參數即可。
找到TsDownloaderMiddleware,這個類就是我們的項目下載器的中間件,我們的代理配置主要寫在process_request函數裏。
改成
def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware.
# Must either:
# - return None: continue processing this request
# - or return a Response object
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of
# installed downloader middleware will be called
# 代理IP由快代理贊助
proxy = '112.192.158.65:20823'
# 做了個處理,http與https
if request.url.startswith("http://"):
request.meta['proxy'] = "http://%s" % proxy
elif request.url.startswith("https://"):
request.meta['proxy'] = "https://%s" % proxy
return None
修改後如圖
settings.py文件也需要修改,需要修改兩處:
1、header參數,記住爬蟲要模擬用戶的真實請求。找到USER_AGENT參數,改成自己瀏覽器的ua,不知道怎麼找ua的同學可以看我前面的一篇教程(點擊跳轉)中有提到。
修改後
2、找到DOWNLOADER_MIDDLEWARES參數,Ctrl + f搜索,註釋掉這個配置保存,啓動配置
註釋後,修改後
好的,在改下我們的爬蟲代碼,spiders目錄下的baidu.py文件。因爲我們用了代理,所以去訪問下查IP的網站,看看是否用上代理了。
# -*- coding: utf-8 -*-
import scrapy
class BaiduSpider(scrapy.Spider):
name = 'baidu'
allowed_domains = ['baidu.com']
start_urls = ['https://www.baidu.com/s?ie=UTF-8&wd=ip']
def parse(self, response):
filename = 'baidu.html'
with open(filename, 'wb') as f:
f.write(response.body)
好的,現在在spiders目錄下運行下,看看有沒有文件出來。
有了,打開文件看下。對吧,這裏查到的IP也是我們在代碼樣例中的IP。說明成功用上代理了。
scrapy使用代理總結下,需要修改及注意那些點。
- 修改中間件文件middleware.py,主要修改downloader中間件的process_request函數。
- 修改配置文件settings.py,設置自己的ua;啓用DOWNLOADER_MIDDLEWARES配置;
嗯,主要注意這兩個點。
其實還有一種設置代理的方法,我就先不寫了,交給大家去研究吧。