一、爬蟲是什么?

#1、什么是互聯網? 互聯網是由網絡設備(網線,路由器,交換機,防火牆等等)和一台台計算機連接而成,像一張網一樣。 #2、互聯網建立的目的? 互聯網的核心價值在於數據的共享/傳遞:數據是存放於一台台計算機上的,而將計算機互聯到一起的目的就是為了能夠方便彼此之間的數據共享/傳遞,否則你只能拿U盤去別人的計算機上拷貝數據了。 #3、什么是上網?爬蟲要做的是什么? 我們所謂的上網便是由用戶端計算機發送請求給目標計算機,將目標計算機的數據下載到本地的過程。 #3.1 只不過,用戶獲取網絡數據的方式是: 瀏覽器提交請求->下載網頁代碼->解析/渲染成頁面。 #3.2 而爬蟲程序要做的就是: 模擬瀏覽器發送請求->下載網頁代碼->只提取有用的數據->存放於數據庫或文件中 #3.1與3.2的區別在於: 我們的爬蟲程序只提取網頁代碼中對我們有用的數據 #4、總結爬蟲 #4.1 爬蟲的比喻: 如果我們把互聯網比作一張大的蜘蛛網,那一台計算機上的數據便是蜘蛛網上的一個獵物,而爬蟲程序就是一只小蜘蛛,沿着蜘蛛網抓取自己想要的獵物/數據 #4.2 爬蟲的定義: 向網站發起請求,獲取資源后分析並提取有用數據的程序 #4.3 爬蟲的價值: 互聯網中最有價值的便是數據,比如天貓商城的商品信息,鏈家網的租房信息,雪球網的證券投資信息等等,這些數據都代表了各個行業的真金白銀,
可以說,誰掌握了行業內的第一手數據,誰就成了整個行業的主宰,如果把整個互聯網的數據比喻為一座寶藏,那我們的爬蟲課程就是來教大家如何來高效地挖掘這些寶藏,
掌握了爬蟲技能,你就成了所有互聯網信息公司幕后的老板,換言之,它們都在免費為你提供有價值的數據。
二、爬蟲的基本流程

#1、發起請求 使用http庫向目標站點發起請求,即發送一個Request Request包含:請求頭、請求體等 #2、獲取響應內容 如果服務器能正常響應,則會得到一個Response Response包含:html,json,圖片,視頻等 #3、解析內容 解析html數據:正則表達式,第三方解析庫如Beautifulsoup,pyquery等 解析json數據:json模塊 解析二進制數據:以b的方式寫入文件 #4、保存數據 數據庫 文
三、請求與響應

#http協議:http://www.cnblogs.com/haiyan123/p/7298967.html #Request:用戶將自己的信息通過瀏覽器(socket client)發送給服務器(socket server) #Response:服務器接收請求,分析用戶發來的請求信息,然后返回數據(返回的數據中可能包含其他鏈接,如:圖片,js,css等) #ps:瀏覽器在接收Response后,會解析其內容來顯示給用戶,而爬蟲程序在模擬瀏覽器發送請求然后接收Response后,是要提取其中的有用數據。
四、Request
#1、請求方式: 常用的請求方式:GET,POST 其他請求方式:HEAD,PUT,DELETE,OPTHONS ps:用瀏覽器演示get與post的區別,(用登錄演示post) post與get請求最終都會拼接成這種形式: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用來保存登錄信息 Referer:上一次的跳轉路徑 一般做爬蟲都會加上請求頭 #4、請求體 如果是get方式,請求體沒有內容 如果是post方式,請求體是format data ps: 1、登錄窗口,文件上傳等,信息都會被附加到請求體內 2、登錄,輸入錯誤的用戶名密碼,然后提交,就可以看到post,正確登錄后頁面通常會跳轉,無法捕捉到post
1 import requests 2 from urllib.parse import urlencode 3 # 請求方式 4 kwords = input("請輸入關鍵字:>>").strip() 5 res = urlencode({"wd":kwords}) # # 請求的url,當你在百度輸入中文的時候,你把url拿下來會變成下面的這樣格式的url,所以得urlencode一下 6 url ="https://www.baidu.com/s?"+res #https://www.baidu.com/s?wd=%E5%9B%BE%E7%89%87 7 8 response = requests.get( 9 # 請求的url,當你在百度輸入中文的時候,你把url拿下來會變成下面的這樣格式的url 10 url, 11 # 請求頭 12 headers={ 13 "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36", 14 }, 15 ) 16 with open("a.html","w",encoding="utf-8") as f: 17 f.write(response.text) 18 # print(response.status_code)
1 kwords = input("請輸入關鍵字:>>").strip() 2 response = requests.get( 3 "https://www.baidu.com/s?", 4 # 請求的url,當你在百度輸入中文的時候,你把url拿下來會變成下面的這樣格式的url 5 params={ 6 "wd":kwords, 7 'pn':20 8 }, 9 # 請求頭 10 headers={ 11 "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36", 12 }, 13 ) 14 with open("b.html","w",encoding="utf-8") as f: 15 f.write(response.text) 16 # print(response.status_code)
五、Response
#1、響應狀態 200:代表成功 301:代表跳轉 404:文件不存在 403:權限 502:服務器錯誤 #2、Respone header Location:跳轉 set-cookie:可能有多個,是來告訴瀏覽器,把cookie保存下來 #3、preview就是網頁源代碼 最主要的部分,包含了請求資源的內容 如網頁html,圖片 二進制數據等
六、總結
#1、總結爬蟲流程: 爬取--->解析--->存儲 #2、爬蟲所需工具: 請求庫:requests,selenium 解析庫:正則,beautifulsoup,pyquery 存儲庫:文件,MySQL,Mongodb,Redis #3、爬蟲常用框架: scrapy
1 import requests #pip3 install requests 2 import re 3 import hashlib 4 import time 5 6 movie_path=r'C:\mp4' 7 8 def get_page(url): 9 try: 10 response=requests.get(url) 11 if response.status_code == 200: 12 return response.text 13 except Exception: 14 pass 15 16 def parse_index(index_page): 17 urls=re.findall('class="items".*?href="(.*?)"',index_page,re.S) 18 for url in urls: 19 if not url.startswith('http'): 20 url='http://www.xiaohuar.com'+url 21 yield url 22 23 def parse_detail(detail_page): 24 l=re.findall('id="media".*?src="(.*?)"',detail_page,re.S) 25 if l: 26 movie_url=l[0] 27 if movie_url.endswith('mp4'): 28 yield movie_url 29 30 def get_movie(url): 31 try: 32 response=requests.get(url) 33 if response.status_code == 200: 34 m=hashlib.md5() 35 m.update(str(time.time()).encode('utf-8')) 36 m.update(url.encode('utf-8')) 37 filepath='%s\%s.mp4' %(movie_path,m.hexdigest()) 38 with open(filepath,'wb') as f: 39 f.write(response.content) 40 print('%s 下載成功' %url) 41 except Exception: 42 pass 43 44 def main(): 45 base_url='http://www.xiaohuar.com/list-3-{page_num}.html' 46 for i in range(5): 47 url=base_url.format(page_num=i) 48 index_page=get_page(url) 49 detail_urls=parse_index(index_page) 50 for detail_url in detail_urls: 51 detail_page=get_page(detail_url) 52 movie_urls=parse_detail(detail_page) 53 for movie_url in movie_urls: 54 get_movie(movie_url) 55 56 if __name__ == '__main__': 57 main()
1 import requests #pip3 install requests 2 import re 3 import hashlib 4 import time 5 from concurrent.futures import ThreadPoolExecutor 6 7 pool=ThreadPoolExecutor(50) 8 movie_path=r'C:\mp4' 9 10 def get_page(url): 11 try: 12 response=requests.get(url) 13 if response.status_code == 200: 14 return response.text 15 except Exception: 16 pass 17 18 def parse_index(index_page): 19 index_page=index_page.result() 20 urls=re.findall('class="items".*?href="(.*?)"',index_page,re.S) 21 for detail_url in urls: 22 if not detail_url.startswith('http'): 23 detail_url='http://www.xiaohuar.com'+detail_url 24 pool.submit(get_page,detail_url).add_done_callback(parse_detail) 25 26 def parse_detail(detail_page): 27 detail_page=detail_page.result() 28 l=re.findall('id="media".*?src="(.*?)"',detail_page,re.S) 29 if l: 30 movie_url=l[0] 31 if movie_url.endswith('mp4'): 32 pool.submit(get_movie,movie_url) 33 34 def get_movie(url): 35 try: 36 response=requests.get(url) 37 if response.status_code == 200: 38 m=hashlib.md5() 39 m.update(str(time.time()).encode('utf-8')) 40 m.update(url.encode('utf-8')) 41 filepath='%s\%s.mp4' %(movie_path,m.hexdigest()) 42 with open(filepath,'wb') as f: 43 f.write(response.content) 44 print('%s 下載成功' %url) 45 except Exception: 46 pass 47 48 def main(): 49 base_url='http://www.xiaohuar.com/list-3-{page_num}.html' 50 for i in range(5): 51 url=base_url.format(page_num=i) 52 pool.submit(get_page,url).add_done_callback(parse_index) 53 54 if __name__ == '__main__': 55 main()
