爬蟲 【第一章】爬蟲基本原理

1、爬蟲是什麼?css

 

#一、什麼是互聯網?
    互聯網是由網絡設備(網線,路由器,交換機,防火牆等等)和一臺臺計算機鏈接而成,像一張網同樣。

#二、互聯網創建的目的?
    互聯網的核心價值在於數據的共享/傳遞:數據是存放於一臺臺計算機上的,而將計算機互聯到一塊兒的目的就是爲了可以方便彼此之間的數據共享/傳遞,不然你只能拿U盤去別人的計算機上拷貝數據了。

#三、什麼是上網?爬蟲要作的是什麼?
    咱們所謂的上網即是由用戶端計算機發送請求給目標計算機,將目標計算機的數據下載到本地的過程。
    #3.1 只不過,用戶獲取網絡數據的方式是:
      瀏覽器提交請求->下載網頁代碼->解析/渲染成頁面。

    #3.2 而爬蟲程序要作的就是:
      模擬瀏覽器發送請求->下載網頁代碼->只提取有用的數據->存放於數據庫或文件中
 
    #3.1與3.2的區別在於:
      咱們的爬蟲程序只提取網頁代碼中對咱們有用的數據

#四、總結爬蟲
    #4.1 爬蟲的比喻:
      若是咱們把互聯網比做一張大的蜘蛛網,那一臺計算機上的數據即是蜘蛛網上的一個獵物,而爬蟲程序就是一隻小蜘蛛,沿着蜘蛛網抓取本身想要的獵物/數據

    #4.2 爬蟲的定義:
      向網站發起請求,獲取資源後分析並提取有用數據的程序 

    #4.3 爬蟲的價值:
      互聯網中最有價值的即是數據,好比天貓商城的商品信息,鏈家網的租房信息,雪球網的證券投資信息等等,這些數據都表明了各個行業的真金白銀,
能夠說,誰掌握了行業內的第一手數據,誰就成了整個行業的主宰,若是把整個互聯網的數據比喻爲一座寶藏,那咱們的爬蟲課程就是來教你們如何來高效地挖掘這些寶藏,
掌握了爬蟲技能,你就成了全部互聯網信息公司幕後的老闆,換言之,它們都在免費爲你提供有價值的數據。

2、爬蟲的基本流程html

#一、發起請求
使用http庫向目標站點發起請求,即發送一個Request
Request包含:請求頭、請求體等

#二、獲取響應內容
若是服務器能正常響應,則會獲得一個Response
Response包含:html,json,圖片,視頻等

#三、解析內容
解析html數據:正則表達式,第三方解析庫如Beautifulsoup,pyquery等
解析json數據:json模塊
解析二進制數據:以b的方式寫入文件

#四、保存數據
數據庫
文

3、請求與響應正則表達式

#http協議:http://www.cnblogs.com/haiyan123/p/7298967.html

#Request:用戶將本身的信息經過瀏覽器(socket client)發送給服務器(socket server)

#Response:服務器接收請求,分析用戶發來的請求信息,而後返回數據(返回的數據中可能包含其餘連接,如:圖片,js,css等)

#ps:瀏覽器在接收Response後,會解析其內容來顯示給用戶,而爬蟲程序在模擬瀏覽器發送請求而後接收Response後,是要提取其中的有用數據。

4、Request數據庫

#一、請求方式:
    經常使用的請求方式:GET,POST
    其餘請求方式:HEAD,PUT,DELETE,OPTHONS

    ps:用瀏覽器演示get與post的區別,(用登陸演示post)

    post與get請求最終都會拼接成這種形式:k1=xxx&k2=yyy&k3=zzz
    post請求的參數放在請求體內:
        可用瀏覽器查看,存放於form data內
    get請求的參數直接放在url後

#二、請求url
    url全稱統一資源定位符,如一個網頁文檔,一張圖片
    一個視頻等均可以用url惟一來肯定

    url編碼
    https://www.baidu.com/s?wd=圖片
    圖片會被編碼(看示例代碼)


    網頁的加載過程是:
    加載一個網頁,一般都是先加載document文檔,
    在解析document文檔的時候,遇到連接,則針對超連接發起下載圖片的請求

#三、請求頭
    User-agent:告訴它這是瀏覽器發過來的請求(請求頭中若是沒有user-agent客戶端配置,服務端可能將你當作一個非法用戶)務必加上
    host
    cookies:cookie用來保存登陸信息
    Referer:上一次的跳轉路徑


    通常作爬蟲都會加上請求頭


#四、請求體
    若是是get方式,請求體沒有內容
    若是是post方式,請求體是format data

    ps:
    一、登陸窗口,文件上傳等,信息都會被附加到請求體內
    二、登陸,輸入錯誤的用戶名密碼,而後提交,就能夠看到post,正確登陸後頁面一般會跳轉,沒法捕捉到post

import requests
from urllib.parse import urlencode
# 請求方式
kwords = input("請輸入關鍵字:>>").strip()
res = urlencode({"wd":kwords}) # # 請求的url,當你在百度輸入中文的時候,你把url拿下來會變成下面的這樣格式的url,因此得urlencode一下
url ="https://www.baidu.com/s?"+res #https://www.baidu.com/s?wd=%E5%9B%BE%E7%89%87json

response = requests.get(
# 請求的url,當你在百度輸入中文的時候,你把url拿下來會變成下面的這樣格式的url
url,
# 請求頭
headers={
"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",
},
)
with open("a.html","w",encoding="utf-8") as f:
f.write(response.text)
# print(response.status_code)瀏覽器

示例代碼1服務器

kwords = input("請輸入關鍵字:>>").strip()
response = requests.get(
"https://www.baidu.com/s?",
# 請求的url,當你在百度輸入中文的時候,你把url拿下來會變成下面的這樣格式的url
params={
"wd":kwords,
'pn':20
},
# 請求頭
headers={
"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",
},
)
with open("b.html","w",encoding="utf-8") as f:
f.write(response.text)
# print(response.status_code)cookie

示例代碼二(和上面的結果是同樣的)網絡

5、Response併發

#一、響應狀態
    200:表明成功
    301:表明跳轉
    404:文件不存在
    403:權限
    502:服務器錯誤

#二、Respone header
    Location:跳轉
    set-cookie:可能有多個,是來告訴瀏覽器,把cookie保存下來
    
#三、preview就是網頁源代碼
    最主要的部分,包含了請求資源的內容
    如網頁html,圖片
    二進制數據等

6、總結

#一、總結爬蟲流程:
    爬取--->解析--->存儲

#二、爬蟲所需工具:
    請求庫:requests,selenium
    解析庫:正則,beautifulsoup,pyquery
    存儲庫:文件,MySQL,Mongodb,Redis

#三、爬蟲經常使用框架:
    scrapy

import requests #pip3 install requests
import re
import hashlib
import time

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):
urls=re.findall('class="items".*?href="(.*?)"',index_page,re.S)
for url in urls:
if not url.startswith('http'):
url='http://www.xiaohuar.com'+url
yield url

def parse_detail(detail_page):
l=re.findall('id="media".*?src="(.*?)"',detail_page,re.S)
if l:
movie_url=l[0]
if movie_url.endswith('mp4'):
yield 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)
index_page=get_page(url)
detail_urls=parse_index(index_page)
for detail_url in detail_urls:
detail_page=get_page(detail_url)
movie_urls=parse_detail(detail_page)
for movie_url in movie_urls:
get_movie(movie_url)

if __name__ == '__main__':
main()

爬取校花網視頻示例一

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()

爬取校花網視頻示例二(加了併發的)

相關文章
相關標籤/搜索