二 同步、非同步、回檔機制
1、同步調用:即提交一個任務後就在原地等待任務結束, 等到拿到任務的結果後再繼續下一行代碼, 效率低下
import requestsdef parse_page(res):print('解析 %s' %(len(res)))def get_page(url):print('下載 %s' %url)response=requests.get(url) if response.status_code == 200: return response.texturls=['https://www.baidu.com/','http://www.sina.com.cn/','https://www.python.org']for url in urls:res=get_page(url) #調用一個任務, 就在原地等待任務結束拿到結果後才繼續往後執行parse_page(res)同步調用
該方案的問題是:
#開啟多進程或都執行緒的方式, 我們是無法無限制地開啟多進程或多執行緒的:在遇到要同時回應成百上千路的連接請求, 則無論多執行緒還是多進程都會嚴重佔據系統資源, 降低系統對外界回應效率, 而且執行緒與進程本身也更容易進入假死狀態。3、改進方案: 執行緒池或進程池+非同步調用:提交一個任務後並不會等待任務結束, 而是繼續下一行代碼
#很多程式師可能會考慮使用“執行緒池”或“連接池”。 “執行緒池”旨在減少創建和銷毀執行緒的頻率, 其維持一定合理數量的執行緒, 並讓空閒的執行緒重新承擔新的執行任務。
改進後方案其實也存在著問題:
#“執行緒池”和“連接池”技術也只是在一定程度上緩解了頻繁調用IO介面帶來的資源佔用。對應上例中的所面臨的可能同時出現的上千甚至上萬次的用戶端請求, “執行緒池”或“連接池”或許可以緩解部分壓力, 但是不能解決所有問題。 總之, 多執行緒模型可以方便高效的解決小規模的服務請求, 但面對大規模的服務請求, 多執行緒模型也會遇到瓶頸, 可以用非阻塞介面來嘗試解決這個問題。
三 、高性能
上述無論哪種解決方案其實沒有解決一個性能相關的問題:IO阻塞,
解決這一問題的關鍵在於, 我們自己從應用程式級別檢測IO阻塞然後切換到我們自己程式的其他任務執行, 這樣把我們程式的IO降到最低, 我們的程式處於就緒態就會增多, 以此來迷惑作業系統, 作業系統便以為我們的程式是IO比較少的程式, 從而會盡可能多的分配CPU給我們, 這樣也就達到了提升程式執行效率的目的
1、在python3.3之後新增了asyncio模組, 可以幫我們檢測IO(只能是網路IO), 實現應用程式級別的切換
2、但asyncio模組只能發tcp級別的請求, 不能發http協議, 因此, 在我們需要發送http請求的時候, 需要我們自訂http報頭
import asyncioimport requestsimport uuiduser_agent='Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'def parse_page(host,res):print('%s 解析結果 %s' %(host,len(res))) with open('%s.html' %(uuid.uuid1()),'wb') as f:f.write(res)@asyncio.coroutinedef get_page(host,port=80,url='/',callback=parse_page,ssl=False):print('下載 http://%s:%s%s' %(host,port,url)) #步驟一(IO阻塞):發起tcp連結, 是阻塞操作, 因此需要yield fromif ssl:port=443recv,send=yield from asyncio.open_connection(host=host,port=443,ssl=ssl) # 步驟二:封裝http協定的報頭, 因為asyncio模組只能封裝並發送tcp包, 因此這一步需要我們自己封裝http協議的包request_headers="""GET %s HTTP/1.0 Host: %s User-agent: %s """ %(url,host,user_agent) # requset_headers="""POST %s HTTP/1.0 Host: %s name=egon&password=123""" % (url, host,)request_headers=request_headers.encode('utf-8') # 步驟三(IO阻塞):發送http請求包send.write(request_headers) yield from send.drain() # 步驟四(IO阻塞):接收回應頭while True:line=yield from recv.readline() if line == b' ': breakprint('%s Response headers:%s' %(host,line)) # 步驟五(IO阻塞):接收回應體text=yield from recv.read() # 步驟六:執行回呼函數callback(host,text) # 步驟七:關閉通訊端send.close() #沒有recv.close()方法, 因為是四次揮手斷連結,雙向連結的兩端,一端發完資料後執行send.close()另外一端就被動地斷開if __name__ == '__main__':tasks=[get_page('www.baidu.com',url='/s?wd=美女',ssl=True),get_page('www.cnblogs.com',url='/',ssl=True),]loop=asyncio.get_event_loop()loop.run_until_complete(asyncio.wait(tasks))loop.close()asyncio+自訂http協議報頭3、自訂http報頭多少有點麻煩,於是有了aiohttp模組,專門幫我們封裝http報頭,然後我們還需要用asyncio檢測IO實現切換
這些事情,原本我們也是可以手動完成的,但如果是單純地複製粘貼,非常耗費時間,比如你想獲取100萬行的資料,大約需忘寢廢食重複工作兩年。而爬蟲可以在一天之內幫你完成,103456743而且完全不需要任何干預。
學習 Python 包並實現基本的爬蟲過程
Python中爬蟲相關的包很多:urllib、requests、bs4、scrapy、pyspider 等,建議你從requests+Xpath 開始,requests 負責連接網站,返回網頁,Xpath 用於解析網頁,便於抽取資料。
2、初識Python爬蟲
Python爬蟲環境搭建
創建第一個爬蟲:爬取百度首頁
爬蟲三步驟:獲取資料、解析資料、保存資料
3、使用Requests爬取豆瓣短評
Requests的安裝和基本用法
用Requests 爬取豆瓣短評資訊
一定要知道的爬蟲協定
4、使用Xpath解析豆瓣短評
解析神器Xpath的安裝及介紹
Xpath的使用:流覽器複製和手寫
實戰:用Xpath 解析豆瓣短評資訊
5、使用pandas保存豆瓣短評資料
pandas 的基本用法介紹
pandas檔保存、資料處理
實戰:使用pandas保存豆瓣短評資料
6、流覽器抓包及headers設置(案例一:爬取知乎)
爬蟲的一般思路:抓取、解析、存儲
流覽器抓包獲取Ajax載入的資料
設置headers 突破反爬蟲限制
實戰:爬取知乎使用者資料
8、Selenium爬取動態網頁(案例三:爬取淘寶)
動態網頁爬取神器Selenium搭建與使用
分析淘寶商品頁面動態資訊
實戰:用Selenium 爬取淘寶網頁資訊
第二章:Python爬蟲之Scrapy框架
1、爬蟲工程化及Scrapy框架初窺
html、css、js、資料庫、http協定、前後臺聯動
爬蟲進階的工作流程
Scrapy元件:引擎、調度器、下載中介軟體、項目管道等
常用的爬蟲工具:各種資料庫、抓包工具等
2、Scrapy安裝及基本使用
Scrapy安裝
Scrapy的基本方法和屬性
開始第一個Scrapy項目
3、Scrapy選擇器的用法
常用選擇器:css、xpath、re、pyquery
css的使用方法
xpath的使用方法
re的使用方法
pyquery的使用方法
4、Scrapy的項目管道
Item Pipeline的介紹和作用
Item Pipeline的主要函數
實戰舉例:將資料寫入檔
實戰舉例:在管道裡過濾資料
5、Scrapy的中介軟體
下載中介軟體和蜘蛛中介軟體
下載中介軟體的三大函數
系統預設提供的中介軟體
6、Scrapy的Request和Response詳解
Request物件基礎參數和高級參數
Request物件方法
Response物件參數和方法
Response物件方法的綜合利用詳解
資料去重
資料入庫MongoDB
第四章:分散式爬蟲及實訓項目
1、大規模併發採集——分散式爬蟲的編寫
分散式爬蟲介紹
Scrapy分散式爬取原理
Scrapy-Redis的使用
Scrapy分散式部署詳解
- 技能拓展:反爬蟲及資料存儲、處理 -
用 Scrapy 爬取租房信息
按照這個流程來學習,你是肯定可以成為一名優秀的爬蟲工程師的!!相信我!
因為是四次揮手斷連結,雙向連結的兩端,一端發完資料後執行send.close()另外一端就被動地斷開if __name__ == '__main__':tasks=[get_page('www.baidu.com',url='/s?wd=美女',ssl=True),get_page('www.cnblogs.com',url='/',ssl=True),]loop=asyncio.get_event_loop()loop.run_until_complete(asyncio.wait(tasks))loop.close()asyncio+自訂http協議報頭
3、自訂http報頭多少有點麻煩,於是有了aiohttp模組,專門幫我們封裝http報頭,然後我們還需要用asyncio檢測IO實現切換
這些事情,原本我們也是可以手動完成的,但如果是單純地複製粘貼,非常耗費時間,比如你想獲取100萬行的資料,大約需忘寢廢食重複工作兩年。而爬蟲可以在一天之內幫你完成,103456743而且完全不需要任何干預。
學習 Python 包並實現基本的爬蟲過程
Python中爬蟲相關的包很多:urllib、requests、bs4、scrapy、pyspider 等,建議你從requests+Xpath 開始,requests 負責連接網站,返回網頁,Xpath 用於解析網頁,便於抽取資料。
2、初識Python爬蟲
Python爬蟲環境搭建
創建第一個爬蟲:爬取百度首頁
爬蟲三步驟:獲取資料、解析資料、保存資料
3、使用Requests爬取豆瓣短評
Requests的安裝和基本用法
用Requests 爬取豆瓣短評資訊
一定要知道的爬蟲協定
4、使用Xpath解析豆瓣短評
解析神器Xpath的安裝及介紹
Xpath的使用:流覽器複製和手寫
實戰:用Xpath 解析豆瓣短評資訊
5、使用pandas保存豆瓣短評資料
pandas 的基本用法介紹
pandas檔保存、資料處理
實戰:使用pandas保存豆瓣短評資料
6、流覽器抓包及headers設置(案例一:爬取知乎)
爬蟲的一般思路:抓取、解析、存儲
流覽器抓包獲取Ajax載入的資料
設置headers 突破反爬蟲限制
實戰:爬取知乎使用者資料
8、Selenium爬取動態網頁(案例三:爬取淘寶)
動態網頁爬取神器Selenium搭建與使用
分析淘寶商品頁面動態資訊
實戰:用Selenium 爬取淘寶網頁資訊
第二章:Python爬蟲之Scrapy框架
1、爬蟲工程化及Scrapy框架初窺
html、css、js、資料庫、http協定、前後臺聯動
爬蟲進階的工作流程
Scrapy元件:引擎、調度器、下載中介軟體、項目管道等
常用的爬蟲工具:各種資料庫、抓包工具等
2、Scrapy安裝及基本使用
Scrapy安裝
Scrapy的基本方法和屬性
開始第一個Scrapy項目
3、Scrapy選擇器的用法
常用選擇器:css、xpath、re、pyquery
css的使用方法
xpath的使用方法
re的使用方法
pyquery的使用方法
4、Scrapy的項目管道
Item Pipeline的介紹和作用
Item Pipeline的主要函數
實戰舉例:將資料寫入檔
實戰舉例:在管道裡過濾資料
5、Scrapy的中介軟體
下載中介軟體和蜘蛛中介軟體
下載中介軟體的三大函數
系統預設提供的中介軟體
6、Scrapy的Request和Response詳解
Request物件基礎參數和高級參數
Request物件方法
Response物件參數和方法
Response物件方法的綜合利用詳解
資料去重
資料入庫MongoDB
第四章:分散式爬蟲及實訓項目
1、大規模併發採集——分散式爬蟲的編寫
分散式爬蟲介紹
Scrapy分散式爬取原理
Scrapy-Redis的使用
Scrapy分散式部署詳解
- 技能拓展:反爬蟲及資料存儲、處理 -
用 Scrapy 爬取租房信息
按照這個流程來學習,你是肯定可以成為一名優秀的爬蟲工程師的!!相信我!