用Scrapy爬取Domain認證的內網數據
只要是瀏覽器裏面能夠訪問的東西,理論上都可以被爬蟲爬取。有了這個信念,基本上所有問題就解決一半啦,笑~
公司內部網絡通常都是由域控制器統一做安全登錄認證,這對於window系的公司尤爲常見。通常爬取內網Domain服務器認證的內部網站,基本都會返回401錯誤,這就是告訴我們沒有通過服務器的認證檢驗。
那麼怎麼做呢?
安裝requests-ntlm認證組件
你需要pip安裝requests-ntlm,這個東西可以幫你完成內網的Request認證。
安裝完成之後記得在ipython裏面測試一下基本的訪問情況:
import requests
from requests_ntlm import HttpNtlmAuth
requests.get("http://internal_protected_site.com",auth=HttpNtlmAuth('domain\\username','password'))
如果仍然返回<Response [401]>
, 那麼你的認證仍然沒有通過。
可能的問題是:
- domain名稱弄錯了:通常我們登錄域認證的機器的時候不需要輸入這個選項,一般是默認設置好的,你得看域管理員配置的是什麼。
- username:也是看域管理員的配置情況,有的域用戶只是名稱,有的有後綴。
- password:這個通常不會出錯
如果返回<Response [200]>
說明組件工作正常了。
封裝組件到Scrapy框架中
我們需要創建Scrapy的Middleware來捕獲所有的Request信息,用requests-ntlm填補上認證信息發送Request,然後返回相應的Response。
簡單的就像這樣:
from scrapy.http import Response
import requests
from requests_ntlm import HttpNtlmAuth
class NTLM_Middleware(object):
def process_request(self, request, spider):
url = request.url
pwd = getattr(spider, 'ntlm_pass', '')
usr = getattr(spider, 'ntlm_user', '')
if not usr:
# 如果Spider中沒有設置ntlm_user屬性,就是普通的網站不在這裏處理了。
return
base64string = base64.b64encode('%s:%s' % (usr, pwd))
request.headers["Authorization"] = "Basic %s" % base64string
s = requests.session()
response = s.get(url,auth=HttpNtlmAuth(usr,pwd))
return Response(url,response.status_code,{}, response.content)
然後在配置setting中啓用組件:
DOWNLOADER_MIDDLEWARES = {
'middlewares.NTLM_Middleware': 510,
}
別忘了在需要爬取內網的蜘蛛內部設置認證的用戶名和密碼:
class DomainSpider(CrawlSpider):
name = "domain.sharepoint"
ntlm_pass = "password"
ntlm_user = "domain\\username"
'''。。。。你的爬取代碼。。。。'''