第一章爬蟲介紹
- 爬蟲的分類
- 通用爬蟲:爬取一整張頁面
- 聚焦爬蟲:爬取頁面中局部的內容
- 增量式爬蟲:去重【重要】
- robots協議
- 反爬機制
- 針對門戶網站
- 反反爬策略
- 正對爬蟲
第二章http和https協議
- 協議概念:基於clinet和server之間的一種通信協議
- 常用請求頭信息:
- User-Agent:請求載體的身份標識
- Connection:
- 常用響應頭信息: Content-Type:
- 三種加密方式:
- 對稱秘鑰加密:
- 非對稱秘鑰加密:
- 證書加密:
第三章 requests模塊
- 請求數據方式(兩個方法+四種方式)
- get請求
- post請求
- 基於Aajx的get/post請求,返回的基本都是json數據
- 【重點注意】url和攜帶的參數
- 用到的參數:
- url
- headers
- 參數:get方法:parma;post方法:data
- 處理代理IP:proxy
- UA偽裝(反反爬策略)
- 爬取基於ajax請求數據的流程
- 使用抓包工具捕獲ajax請求對應的數據包
- 從數據包中提取url和對應的請求參數
- 請求的發送(處理參數)
- 獲取json格式響應數據 response.json()
- 爬取圖片數據的方式
- with open方法
- urllib.request.urlretrive(url,filename)
- 實現模擬登陸
- 如何實現模擬登錄:登錄后發起post請求,獲得數據包url及參數
- 為什么模擬登錄
- 獲取cookie
- 需要獲取基於用戶的用戶信息
- 處理cookie(反反爬策略)
- requests.Session()返回session對象,如果有cookie的話,將cookie自動存儲到session中
- 驗證碼識別(反反爬策略)
- 使用雲打碼平台處理驗證碼
- 設置代理(反反爬策略)
- get(proxies = {'http/https':'ip:port'} )
- 使用線程池(multiprocessing.dummy.Pool)實現數據爬取
- pool = Pool(5) # 開啟5個線程
- list = pool.map(func,list) # func異步對list中的元素進行操作
第四章 數據解析
- 正則解析
- xpath解析
- 解析原理:
- 標簽的定位
- 取數據
- xpath插件
- /相對路徑 //絕對路徑
- /text()指定文本 //text()所有文本
- li.xpath('./')
- 數據加密-煎蛋網(反反爬策略)
- 分析js使用bytes64解密
- 【重點】如何判斷頁面數據是否為動態加載出來的
- 抓包工具中response中存放的數據才是我們用requests請求到的數據,response中源碼數據與elements中顯示的數據不一樣
- 爬取全國所有城市名稱(xpath表達式的特殊使用 | )
- 或運算符 | :匹配多個xpath表達式
- 常見錯誤處理:HTTPConnectionPool(host:XX)Max retries exceeded with url
- ip被禁,連接池資源滿了,請求頻率過高
- 解決方法:
- Connection:'close'
- 使用代理ip
- sleep
- 解析原理:
- bs4解析
- soup.elementName# 定位到第一次出現的該標簽
- find()返回單數 findall()返回復數
- select('選擇器')層級選擇器
- 取屬性
- .string直系文本內容
- .text;.get_text()非直系全部內容
- ['href']定位改標簽並去除屬性值
第五章 驗證碼處理
第六章 動態數據加載
- 通用方法捕獲動態加載的數據
- selenium+phantomjs:
- 注意使用瀏覽器的驅動程序
- phantomjs既是瀏覽器也是瀏覽器的驅動,可以使用在無界面瀏覽的環境中
- get()發請求
- find_xxx標簽定位
- click點擊操作
- send_keys()文本框中出入數據
- excute_script('js')執行js代碼
- switch_to().frame(id):iframe 定位iframe的id
- selenium+phantomjs:
第七章 移動端數據爬取
- 需要的登錄的軟件,爬取數據時很難的
第八章 scrapy框架基礎+持久化存儲
- spider文件
- name 爬蟲文件的名稱,爬蟲文件的唯一標識
- start_urls 起始url列表
- parse 解析數據
- 持久化存儲方式:
- 基於終端指令:將parse方法的返回值存儲到本地,文件類型有要求
- 基於管道:
- 獲取解析的數據,response.xpath進行數據解析
- 將解析的數據封裝到item類型的對象中
- 向管道提交item:使用yield
- 在管道的process_item方法中執行持久化存儲操作
- 在配置文件中開啟管道
- 注意:
- process_item會被調用多次,當爬蟲文件每執行一個yield item時,都會執行process_item文件
- process_item的返回值:將item傳遞給下一個管道類
第九章 遞歸解析和post請求
- 遞歸解析:手動請求發送
- 為什么使用手動請求發送
- 分頁請求操作
- yield scrapy.Request(url,callback)
- 為什么使用手動請求發送
- post請求【基本不發送post請求】
- 重寫start_request()方法:(自動處理cookie)
- yield scrapy.FormRequest(url,callback,formdata)
第十章 日志等級和請求傳參
- 日志等級
- setting文件中添加
- LOG_LEVEL
- LOG_FILE
- 什么時候會用到請求傳參:當解析的數據不在同一張頁面的情況下.
- scrapy.Request(url,callback,meta={})
- response.meta['key']
- setting文件中添加
第十一章 UA池和代理池
- 下載中間件:攔截請求和響應
- 攔截請求
- 處理UA
- process_request(request):
request.headers['User-Agent'] = 'xxxx' UA池
- 攔截響應
- process_response
- 攔截異常
- process_exception:
- request.meta['proxy'] = 'http://ip:port' 代理池;當請求發生異常時才處理ip
第十二章 scrapy中selenium的應用
- spider的init構造方法中實例化一個瀏覽器對象(bro)
- spider的closed(self,spider)執行關閉瀏覽器操作
- 在中間件的process_response執行瀏覽器自動化的操作(get,page_source)獲取頁面源碼數據
- 實例化一個新的響應對象(scrapy.http.HTMLResponse(body=page_source))
- 返回響應對象
- 在配置文件中開啟中間件
第十三章 全站數據爬取
- CrawlSpider:scrapy genspider -t crawl xxx www.xxx.com
- 連接提取器:LinkExtactor(allow='xxxx')
- 規則解析器:Rule(link,callback,follow=True)
第十四章 分布式爬蟲
第十五章 增量式爬蟲
數據分析
- numpy
- 切片 arr[index,col]
- 變形:reshape()
- 級聯:concatnate()
- 切分:spilt
- 排序:sort
- Series
- 過濾空值
- 去重:unique()
- DataFrame
- 創建
- 索引
- 取列:
- 取行:
- 取元素:
- 切片:
- 切列:df.loc[:,col]
- 切行:df[:]
- 空值檢測和過濾
- 數據清洗的4種方式:將控制所對應的行刪掉;將控制做覆蓋;將重復行刪掉;將異常值進行檢測過濾
- 空值檢測函數:
- isnull.any(axis) notnull.all(axis)
- 空值過濾思路:
- 將檢測函數的結果直接作為df的索引值,將空值所在的行或列過濾掉;
- 空值過濾函數:
- dropna(axis=0) 直接進行檢測和過濾,axis的0/1與其他函數相反
- 檢測重復行:
- drop_duplicated(keep) 檢測到哪些行是重復的,參數keep為保留,
- 覆蓋控制:
- fillna(method,axis) 方法method=ffill/bfill向前或向后填充
- 過濾重復行:
- 隨機取樣:
- take([3,1,2,0],axis=1) 第一個參數放行/列的隱式索引的排序規則,axis的0/1與其他函數相反
- random.permutaion(5) 生成隨機序列,作為take中的參數一,配合take使用
- 級聯機制:concat(),保留控制outer
- 合並機制:merge,數據的合並
- 替換:replace(to_replace,value)
- 映射:map()做映射或充當運算工具:Series.map(func);apply()比map()效率高
- 分組:df.groupby(by)['xxx'].mean()
- 分組聚合:
- df.groupby(by)['xxx'].apply(func)
- 條件查詢函數:df.query('字符串形式的條件')