原文:https://blog.csdn.net/qq_30242609/article/details/70859891
Headless組件ChromeDriver
selenium3.x已經不支持PhantomJS,所以可以使用firifox或者chrome的headless方案
Selenium
Selenium是一個自動化的測試工具,這裏主要用到了它的Webdriver操作瀏覽器。python下載selenium庫即可,建議使用conda工具下載
說明
scrapy通過selenium使用ChromeDriver進行headless操作,爬取已經加載js的頁面(即動態生成html的頁面)
scrapy下載器中間件介紹
Scrapy - Downloader Middleware
Scrapy不再詳細介紹,這裏主要會用到Downloader Middleware, 下載器中間件。
下載器中間件在下載器和Scrapy引擎之間,每一個request和response都會通過中間件進行處理。在中間件中,對request進行處理的函數是process_request(request, spider)
process_request中調用selenium來訪問頁面,獲取js加載後的完整頁面,代碼如下
# 進程請求方法改成用selenium請求
def process_request(self, request, spider):
content = self.selenium_request(request.url);
if content.strip() != '':
return HtmlResponse(request.url, encoding='utf-8', body=content, request=request)
return None
# return None
return HtmlResponse(request.url, encoding='utf-8', body=content, request=request)
裏面調用selenium_request請求頁面,代碼如下
# selenium獲取頁面瀏覽器內容
def selenium_request(self, url):
# js控制瀏覽器滾動到底部js
js = """
function scrollToBottom() {
var Height = document.body.clientHeight, //文本高度
screenHeight = window.innerHeight, //屏幕高度
INTERVAL = 100, // 滾動動作之間的間隔時間
delta = 500, //每次滾動距離
curScrollTop = 0; //當前window.scrollTop 值
console.info(Height)
var scroll = function () {
//curScrollTop = document.body.scrollTop;
curScrollTop = curScrollTop + delta;
window.scrollTo(0,curScrollTop);
console.info("偏移量:"+delta)
console.info("當前位置:"+curScrollTop)
};
var timer = setInterval(function () {
var curHeight = curScrollTop + screenHeight;
if (curHeight >= Height){ //滾動到頁面底部時,結束滾動
clearInterval(timer);
}
scroll();
}, INTERVAL)
};
scrollToBottom()
"""
chrome_options = webdriver.ChromeOptions()
# headless無界面模式
chrome_options.add_argument("--headless")
chrome_options.add_argument("--disable-gpu")
driver = webdriver.Chrome(chrome_options=chrome_options,executable_path="D:\\開發\chromedriver_win32\\chromedriver")
driver.get(url)
# driver.maximize_window();# 窗口最大化
# 執行js滾動瀏覽器窗口到底部
driver.execute_script(js)
# time.sleep(5) # 不加載圖片的話,這個時間可以不要,等待JS執行
# driver.get_screenshot_as_file("C:\\Users\\Administrator\\Desktop\\test.png")
content = driver.page_source.encode('utf-8')
# driver.quit()
driver.close()
# return None
return content
其中的js是用於滾動瀏覽器到底部,因爲一些網頁的圖片是滾動到某個地方纔會加載圖片。如果需要爬取圖片url的,就需要調用這個js滾動瀏覽器。作者的js試過有點問題,後面我稍微調整了下
測試時發現,如果等待JS執行的時間過短,會導致爬取的頁面靠近底部的圖片沒能加載,因爲滾動函數還未執行到此處。所以需要預留一個稍微長一點的等待時間
# time.sleep(5) # 不加載圖片的話,這個時間可以不要,等待JS執行
最後開啓下載中間件,在settings.py文件中
DOWNLOADER_MIDDLEWARES = {
'mytest.middlewares.MytestDownloaderMiddleware': 543,
}