what's the 爬蟲?
了解爬蟲之前,我們首先要知道什么是互聯網
1、什么是互聯網?
互聯網是由網絡設備(網線,路由器,交換機,防火牆等等)和一台台計算機連接而成,總體上像一張網一樣。
2、互聯網建立的目的?
互聯網的核心價值在於數據的共享和傳遞:數據是存放於一台台計算機上的,而將計算機互聯到一起的目的就是為了能夠方便彼此之間的數據共享/傳遞,否則你只能拿U盤去別人的計算機上拷貝數據了。
3、什么是上網?爬蟲要做的是什么?
我們所謂的上網便是由用戶端計算機發送請求給目標計算機,將目標計算機的數據下載到本地的過程。
只不過,用戶獲取網絡數據的方式是: 瀏覽器提交請求->下載網頁代碼->解析/渲染成頁面。
而爬蟲程序要做的就是: 模擬瀏覽器發送請求->下載網頁代碼->只提取有用的數據->存放於數據庫或文件中
區別在於:我們的爬蟲程序只提取網頁代碼中對我們有用的數據
4、總結爬蟲
如果我們把互聯網比作一張大的蜘蛛網,那一台計算機上的數據便是蜘蛛網上的一個獵物,而爬蟲程序就是一只小蜘蛛,沿着蜘蛛網抓取自己想要的獵物/數據,這就是爬蟲。
爬蟲的定義:向網站發起請求,獲取資源后分析並提取有用數據的程序
爬蟲的價值:互聯網中最有價值的便是數據,比如天貓商城的商品信息,鏈家網的租房信息,雪球網的證券投資信息等等,這些數據都代表了各個行業的真金白銀,可以說,誰掌握了行業內的第一手數據,誰就成了整個行業的主宰,如果把整個互聯網的數據比喻為一座寶藏,那我們的爬蟲課程就是來教大家如何來高效地挖掘這些寶藏,掌握了爬蟲技能,你就成了所有互聯網信息公司幕后的老板,換言之,它們都在免費為你提供有價值的數據。
爬蟲的基本流程
1、發起請求
使用http庫向目標站點發起請求,即發送一個Request
Request包含:請求頭、請求體等
2、獲取響應內容
如果服務器能正常響應,則會得到一個Response
Response包含:html,json,圖片,視頻等
3、解析內容
解析html數據:可以利用正則表達式,第三方解析庫如Beautifulsoup,pyquery等
解析json數據:json模塊
解析二進制數據:以b的方式寫入文件(圖片和視頻)
4、保存數據
數據庫、文件
請求與相應
http協議:參考博客——http://www.cnblogs.com/linhaifeng/articles/8243379.html
Request:用戶將自己的信息通過瀏覽器(socket client)發送給服務器(socket server)
Response:服務器接收請求,分析用戶發來的請求信息,然后返回數據(返回的數據中可能包含其他鏈接,如:圖片,js,css等)
ps:瀏覽器在接收Response后,會解析其內容來顯示給用戶,而爬蟲程序在模擬瀏覽器發送請求然后接收Response后,是要提取其中的有用數據。
請求Request
1、請求方式:
常用的請求方式:GET,POST
其他請求方式(基本不用):HEAD,PUT,DELETE,OPTHONS
post與get請求最終都會在url上拼接成這種形式:k1=xxx&k2=yyy&k3=zzz
post請求的參數放在請求體內,可用瀏覽器查看,存放於form data內
get請求的參數直接放在url的?后
2、請求url
url全稱統一資源定位符,如一個網頁文檔,一張圖片,一個視頻等都可以用url唯一來確定
url編碼:https://www.baidu.com/s?wd=圖片(這時的圖片會被編碼)
網頁的加載過程是:加載一個網頁,通常都是先加載document文檔,在解析document文檔的時候,遇到鏈接,則針對超鏈接發起下載圖片的請求
3、請求頭
User-agent:請求頭中如果沒有user-agent客戶端配置,服務端可能將你當做一個非法用戶
host
cookies:cookie用來保存登錄信息
注:一般做爬蟲都會加上請求頭
4、請求體
如果是get方式,請求體沒有內容
如果是post方式,請求體是format data
ps:
1、登錄窗口,文件上傳等,信息都會被附加到請求體內
2、登錄,輸入錯誤的用戶名密碼,然后提交,就可以看到post,正確登錄后頁面通常會跳轉,無法捕捉到post
響應Response
1、主要的響應狀態
狀態代碼有三位數字組成,第一個數字定義了響應的類別,共分五種類別: 1xx:指示信息--表示請求已接收,繼續處理 2xx:成功--表示請求已被成功接收、理解、接受 3xx:重定向--要完成請求必須進行更進一步的操作 4xx:客戶端錯誤--請求有語法錯誤或請求無法實現 5xx:服務器端錯誤--服務器未能實現合法的請求 常見狀態碼: 200 OK #客戶端請求成功 400 Bad Request #客戶端請求有語法錯誤,不能被服務器所理解 401 Unauthorized #請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用 403 Forbidden #服務器收到請求,但是拒絕提供服務 404 Not Found #請求資源不存在,eg:輸入了錯誤的URL 500 Internal Server Error #服務器發生不可預期的錯誤 503 Server Unavailable #服務器當前不能處理客戶端的請求,一段時間后可能恢復正常
2、Respone header
set-cookie:可能有多個,是來告訴瀏覽器,把cookie保存下來
3、preview就是網頁源代碼
最主要的部分,包含了請求資源的內容,如網頁html,圖片,二進制數據等
總結
#1、總結爬蟲流程: 爬取--->解析--->存儲 #2、爬蟲所需工具: 請求庫:requests,selenium 解析庫:正則,beautifulsoup,pyquery 存儲庫:文件,MySQL,Mongodb,Redis #3、爬蟲常用框架: scrapy

# import requests #pip3 install requests import re import hashlib import time from concurrent.futures import ThreadPoolExecutor pool=ThreadPoolExecutor(50) movie_path=r'C:\mp4' def get_page(url): try: response=requests.get(url) if response.status_code == 200: return response.text except Exception: pass def parse_index(index_page): index_page=index_page.result() urls=re.findall('class="items".*?href="(.*?)"',index_page,re.S) for detail_url in urls: if not detail_url.startswith('http'): detail_url='http://www.xiaohuar.com'+detail_url pool.submit(get_page,detail_url).add_done_callback(parse_detail) def parse_detail(detail_page): detail_page=detail_page.result() l=re.findall('id="media".*?src="(.*?)"',detail_page,re.S) if l: movie_url=l[0] if movie_url.endswith('mp4'): pool.submit(get_movie,movie_url) def get_movie(url): try: response=requests.get(url) if response.status_code == 200: m=hashlib.md5() m.update(str(time.time()).encode('utf-8')) m.update(url.encode('utf-8')) filepath='%s\%s.mp4' %(movie_path,m.hexdigest()) with open(filepath,'wb') as f: f.write(response.content) print('%s 下載成功' %url) except Exception: pass def main(): base_url='http://www.xiaohuar.com/list-3-{page_num}.html' for i in range(5): url=base_url.format(page_num=i) pool.submit(get_page,url).add_done_callback(parse_index) if __name__ == '__main__': main() # print(re.findall('\w','hello egon 123')) # print(re.findall('h.*?src="(.*?)"','he src="(dg)" haaa src="(dssg)" egon 123'))

# ####################gif########### # import requests #pip3 install requests # import re # import hashlib # import time # from concurrent.futures import ThreadPoolExecutor # # pool=ThreadPoolExecutor(50) # movie_path=r'D:\python代碼文件存放目錄\S6\1.16\爬蟲一 煎蛋\GIF' # # def get_page(url): # try: # response=requests.get(url) # if response.status_code == 200: # return response.text # except Exception: # pass # # def parse_index(index_page): # index_page=index_page.result() # print('111111111',index_page) # urls=re.findall('style="text-align:center;".*?src="(.*?)"',index_page,re.S) # print('22222',urls) # for detail_url in urls: # # if not detail_url.startswith('http'): # # detail_url='http://www.xiaohuar.com'+detail_url # print('-----', detail_url) # if detail_url.endswith('gif'): # pool.submit(get_movie,detail_url) # # pool.submit(get_page,detail_url).add_done_callback(parse_detail) # # # def parse_detail(detail_page): # # detail_page=detail_page.result() # # print('===',detail_page) # # l=re.findall('img.*?src="(.*?)"',detail_page,re.S) # # print(l) # # if l: # # # # movie_url=l[0] # # if movie_url.endswith('gif'): # # pool.submit(get_movie,movie_url) # # def get_movie(url): # try: # response=requests.get(url) # if response.status_code == 200: # m=hashlib.md5() # m.update(str(time.time()).encode('utf-8')) # m.update(url.encode('utf-8')) # filepath='%s\%s.gif' %(movie_path,m.hexdigest()) # with open(filepath,'wb') as f: # f.write(response.content) # print('%s 下載成功' %url) # except Exception: # pass # # def main(): # base_url = 'http://www.tufutv.com/news/8.html' # for i in range(1): # # url=base_url.format(page_num=i) # pool.submit(get_page,base_url).add_done_callback(parse_index) # # if __name__ == '__main__': # main() #############煎蛋網########## import requests #pip3 install requests import re import hashlib import time import os from concurrent.futures import ThreadPoolExecutor pool=ThreadPoolExecutor(50) movie_path=r'D:\python代碼文件存放目錄\S6\1.16\爬蟲一 煎蛋\煎蛋網' def get_page(url,i): print(i) try: response=requests.get(url) if response.status_code == 200: return [response.text,i] except Exception: pass def parse_index(index_page): print(index_page,type(index_page)) index_page=index_page.result() print(index_page, type(index_page)) i = index_page[1] print(i) index_page=index_page[0] # print('111111111',index_page) urls=re.findall('class="aligncenter".*?src="(.*?)"',index_page,re.S) print('22222',urls) for detail_url in urls: # if not detail_url.startswith('http'): # detail_url='http://www.xiaohuar.com'+detail_url print('-----', detail_url) if detail_url.endswith('gif'): a='gif' elif detail_url.endswith('jpg'): a = 'jpg' pool.submit(get_movie,detail_url,a,i) # pool.submit(get_page,detail_url).add_done_callback(parse_detail) # def parse_detail(detail_page): # detail_page=detail_page.result() # print('===',detail_page) # l=re.findall('img.*?src="(.*?)"',detail_page,re.S) # print(l) # if l: # # movie_url=l[0] # if movie_url.endswith('gif'): # pool.submit(get_movie,movie_url) def get_movie(url,a,i): print(a,i) try: print('try') response=requests.get(url) if response.status_code == 200: print(200) m=hashlib.md5() m.update(str(time.time()).encode('utf-8')) m.update(url.encode('utf-8')) if not os.path.exists(movie_path + r'\%s'%i): os.makedirs(movie_path + r'\%s' % i) filepath='%s\%s\%s.%s' %(movie_path,i,m.hexdigest(),a) with open(filepath,'wb') as f: f.write(response.content) print('%s 下載成功' %url) except Exception : print(111111111) def main(): base_url = 'http://www.yikeyouzi.com/201604056806/{page_num}' for i in range(42,43): url=base_url.format(page_num=i) pool.submit(get_page,url,i).add_done_callback(parse_index) time.sleep(3) if __name__ == '__main__': main()
后續知識