爬蟲基礎02-day24
阿新 • • 發佈:2017-10-28
html send ont http 序列化 switch 知乎 初始 robot
寫在前面
上課第24天,打卡:
努力不必讓全世界知道;
1 s16/17爬蟲2 2 3 內容回顧: 4 1. Http協議 5 Http協議:GET / http1.1/r/n...../r/r/r/na=1 6 TCP協議:sendall("GET / http1.1/r/n...../r/r/r/na=1") 7 8 2. 請求體 9 GET: GET / http1.1/r/n...../r/r/r/n 10 POST: 11武Sir - 筆記POST / http1.1/r/n...../r/r/r/na=1&b=2 12 POST / http1.1/r/n...../r/r/r/{"k1":123} 13 14 PS: 依據Content-Type請求頭 15 16 3. requests模塊 17 - method 18 - url 19 - params 20 - data 21 - json22 - headers 23 - cookies 24 - proxies 25 4. BeautifulSoup4模塊 26 HTML 27 XML 28 29 5. Web微信 30 - 輪訓 31 - 長輪訓 32 33 34 35 今日內容概要: 36 1. Web微信 37 38 2. 高性能相關 39 403. Scrapy 41 42 43 內容詳細: 44 1. Web微信 45 46 - 防盜鏈 47 - headers 48 - cookies 49 50 - 檢測請求 51 - url 52 53 - Session中: 54 - qcode 55 - ctime 56 - login_cookie_dict 57 - ticket_dict_cookie 58 - ticket_dict 59 - init_cookie_dict 60 61 - 收發消息 62 63 64 65 2. 高性能相關 66 67 基本原理: 68 IO多路復用:select,用於檢測socket對象是否發生變化(是否連接成功,是否有數據到來) 69 Socket:socket客戶端 70 71 import socket 72 import select 73 74 class Request(object): 75 def __init__(self,sock,func,url): 76 self.sock = sock 77 self.func = func 78 self.url = url 79 80 def fileno(self): 81 return self.sock.fileno() 82 83 def async_request(url_list): 84 85 input_list = [] 86 conn_list = [] 87 88 for url in url_list: 89 client = socket.socket() 90 client.setblocking(False) 91 # 創建連接,不阻塞 92 try: 93 client.connect((url[0],80,)) # 100個向百度發送的請求 94 except BlockingIOError as e: 95 pass 96 97 obj = Request(client,url[1],url[0]) 98 99 input_list.append(obj) 100 conn_list.append(obj) 101 102 while True: 103 # 監聽socket是否已經發生變化 [request_obj,request_obj....request_obj] 104 # 如果有請求連接成功:wlist = [request_obj,request_obj] 105 # 如果有響應的數據: rlist = [request_obj,request_obj....client100] 106 rlist,wlist,elist = select.select(input_list,conn_list,[],0.05) 107 for request_obj in wlist: 108 # print(‘連接成功‘) 109 # # # # 發送Http請求 110 # print(‘發送請求‘) 111 request_obj.sock.sendall("GET / HTTP/1.0\r\nhost:{0}\r\n\r\n".format(request_obj.url).encode(‘utf-8‘)) 112 conn_list.remove(request_obj) 113 114 for request_obj in rlist: 115 data = request_obj.sock.recv(8096) 116 request_obj.func(data) 117 request_obj.sock.close() 118 input_list.remove(request_obj) 119 120 if not input_list: 121 break 122 123 使用一個線程完成並發操作,如何並發? 124 當第一個任務到來時,先發送連接請求,此時會發生IO等待,但是我不等待,我繼續發送第二個任務的連接請求.... 125 126 IO多路復用監聽socket變化 127 先連接成功: 128 發送請求信息: GET / http/1.0\r\nhost.... 129 遇到IO等待,不等待,繼續檢測是否有人連接成功: 130 發送請求信息: GET / http/1.0\r\nhost.... 131 遇到IO等待,不等待,繼續檢測是否有人連接成功: 132 發送請求信息: GET / http/1.0\r\nhost.... 133 134 有結果返回: 135 讀取返回內容,執行回調函數 136 讀取返回內容,執行回調函數 137 讀取返回內容,執行回調函數 138 讀取返回內容,執行回調函數 139 讀取返回內容,執行回調函數 140 讀取返回內容,執行回調函數 141 讀取返回內容,執行回調函數 142 143 144 145 問題:什麽是協程? 146 單純的執行一端代碼後,調到另外一端代碼執行,再繼續跳... 147 148 異步IO: 149 - 【基於協程】可以用 協程+非阻塞socket+select實現,gevent 150 - 【基於事件循環】完全通用socket+select實現,Twsited 151 152 1. 如何提高爬蟲並發? 153 利用異步IO模塊,如:asyncio,twisted,gevent 154 本質: 155 - 【基於協程】可以用 協程+非阻塞socket+select實現,gevent 156 - 【基於事件循環】完全通用socket+select實現,Twsited,tornado 157 158 2. 異步非阻塞 159 異步:回調 select 160 非阻塞:不等待 setblocking(False) 161 162 3. 什麽是協程? 163 pip3 install gevent 164 165 from greenlet import greenlet 166 167 def test1(): 168 print(12) 169 gr2.switch() 170 print(34) 171 gr2.switch() 172 173 174 def test2(): 175 print(56) 176 gr1.switch() 177 print(78) 178 179 gr1 = greenlet(test1) 180 gr2 = greenlet(test2) 181 gr1.switch() 182 183 184 185 3. 爬蟲 186 - request+bs4+twisted或gevent或asyncio 187 - scrapy框架 188 - twisted 189 - 自己html解析 190 - 限速 191 - 去重 192 - 遞歸,找4層 193 - 代理 194 - https 195 - 中間件 196 .... 197 - 安裝scrapy 198 依賴Twisted 199 200 - 開始寫爬蟲 201 執行命令: 202 scrapy startproject sp1 203 204 sp1 205 - sp1 206 - spiders 爬蟲 207 - xx.py 208 - chouti.py 209 - middlewares 中間件 210 - pipelines 持久化 211 - items 規則化 212 - settings 配置 213 - scrapy.cfg 214 215 cd sp1 216 scrapy genspider xx xx.com 217 scrapy genspider chouti chouti.com 218 219 - scrapy crawl chouti 220 name 221 allow_domains 222 start_urls 223 224 parse(self,response) 225 226 227 yield Item 228 229 yield Request(url,callback) 230 231 232 本周任務: 233 1. Web微信 234 235 2. 高性能示例保存 236 237 3. 238 - 煎蛋 239 - 拉鉤 240 - 知乎 241 - 抽屜 242
day24 Web微信 高性能 scrapy requests.post(data=xxx) -> Form Data requests.post(json=xxx) -> Request Payload HttpResponse() 參數可以是字符串也可以是字節 response.text 字符串 response.content 字節 # 獲取最近聯系人然後進行初始化 # 獲取頭像 # 拿聯系人列表 response = requests.get(url,cookies=xxx) response.encoding = ‘utf-8‘ print(json.loads(response.text)) Web微信總結 - 頭像防盜鏈 - headers - cookies - 檢測請求: - tip | pass_ticket | ... - redirect_url和真實請求的url是否一致 - session 保存關鍵點的cookies和關鍵變量值 - qrcode 和 ctime - login_cookie_dict - ticket_dict_cookie - ticket_dict - init_cookie_dict - init_dict - all_cookies = {} - all_cookies.update(...) json序列化的時候是可以加參數的: data = { ‘name‘:‘alex‘, ‘msg‘:‘中文asa‘ } import json print(json.dumps(data)) 按Unicode顯示 print(json.dumps(data,ensure_ascii=False)) 按中文顯示 json.dumps() 之後是字符串 requests.post() 默認是按照 latin-1 編碼,不支持中文 所以改成直接發bytes: requests.post(data=json.dumps(data,ensure_ascii=False).encode(‘utf-8‘)) 發送消息需帶上cookies 發送消息 檢測是否有新消息到來 接收消息 ######################### 高性能相關 100張圖片,下載 使用一個線程完成並發操作 是配合IO多路復用完成的 爬蟲: - 簡單的爬蟲 - requests+bs4+twsited+asyncio - scrapy框架 - 下載頁面:twsited - 解析頁面:自己的HTML解析 - 可限速 - 去重 - 遞歸 一層一層的爬,成倍速的增長,還可以限制層數 - 代理 - https - 中間件 ... scrapy - scrapy startproject sp1 - cd sp1 - scrapy genspider baidu baidu.com - scrapy genspider chouti chouti.com - scrapy crawl chouti --nolog - name - allow_dimains - start_urls - parse(self,response) - yield Item 持久化 - yield Request(url,callback) 把url放到調度器隊列裏 本周作業: 1.Web微信 自己去寫,寫完跟老師的對比 2.高性能總結文檔(源碼示例+文字理解) 3.任意找一個網站,用Scrapy去爬 - 煎蛋 - 拉鉤 - 知乎 - 抽屜 - ... 不遵循爬蟲規範: ROBOTSTXT_OBEY = False 可能會失敗:沒有帶請求頭 起始url如何攜帶指定請求頭? 自定義start_requests(self)
一、Web微信
獲取最近聯系人列表並初始化:
獲取聯系人列表:
代碼實現見另一片博客:Web微信
二、高性能編程示例
參考:http://www.cnblogs.com/wupeiqi/articles/6229292.html
代碼示例見另一篇那博客:Python高性能編程
三、Scrapy框架初探
爬蟲基礎02-day24