爬蟲流程
- 發起請求,通過使用HTTP庫向目標站點發起請求,即發送一個Request,請求可以包含額外的headers等信息,並等待服務器響應。
- 獲取響應內容如果服務器能正常響應,則會得到一個Response,Response的內容就是所要獲取的頁面內容,其中會包含:html,json,圖片,視頻等。
- 解析內容得到的內容可能是html數據,可以使用正則表達式、第三方解析庫如Beautifulsoup,etree等,要解析json數據可以使用json模塊,二進制數據,可以保存或者進一步的處理。
- 保存數據保存的方式比較多元,可以存入數據庫也可以使用文件的方式進行保存。
正則表達式
正則表達式(regular expression),又稱規則表達式,通常被用來檢索、替換那些符合某個模式(規則)的文本。正則表達式是對字符串操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個“規則字符串”,這個“規則字符串”用來表達對字符串的一些過濾邏輯。在Python中正則表達式通過re模塊來實現。
正則表達式匹配規則
符號 |
說明 |
. |
用於匹配任意一個字符,如 a.c 可以匹配 abc 、aac 、akc 等 |
^ |
用於匹配以...開頭的字符,如 ^abc 可以匹配 abcde 、abcc 、abcak 等 |
$ |
用於匹配以...結尾的字符,如 abc$ 可以匹配 xxxabc 、123abc 等 |
* |
匹配前一個字符零次或多次,如 abc* 可以匹配 ab 、abc 、abcccc 等 |
+ |
匹配前一個字符一次或多次,如 abc+ 可以匹配 abc 、abcc 、abcccc 等 |
? |
匹配前一個字符零次或一次,如 abc? 只能匹配到 ab 和 abc |
\ |
轉義字符,比如我想匹配 a.c ,應該寫成 a\.c ,否則 . 會被當成匹配字符 |
| |
表示左右表達式任意匹配一個,如 aaa|bbb 可以匹配 aaa 也可以匹配 bbb |
[ ] |
匹配中括號中的任意一個字符,如 a[bc]d 可以匹配 abd 和 acd,也可以寫一個範圍,如 [0-9] 、[a-z] 等 |
( ) |
被括起來的表達式將作爲一個分組,如 (abc){2} 可以匹配 abcabc ,a(123|456)b 可以匹配 a123b 或 a456b |
{m} |
表示匹配前一個字符m次,如 ab{2}c 可以匹配 abbc |
{m,n} |
表示匹配前一個字符 m 至 n 次,如 ab{1,2}c 可以匹配 abc 或 abbc |
\d |
匹配數字,如 a\dc 可以匹配 a1c 、a2c 、a3c 等 |
\D |
匹配非數字,也就是除了數字之外的任意字符或符號,如 a\Dc 可以匹配 abc 、aac 、a.c 等 |
\s |
匹配空白字符,也就是匹配空格、換行符、製表符等等,如 a\sc 可以匹配 'a c' 、a\nc 、a\tc 等 |
\S |
匹配非空白字符,也就是匹配空格、換行符、製表符等之外的其他任意字符或符號,如 a\Sc 表示除了 'a c' 之外都能匹配,abc 、a3c 、a.c 等 |
\w |
匹配大小寫字母和數字,也就是匹配 [a-zA-Z0-9] 中的字符,如 a\wc 可以匹配 abc 、aBc 、a2c 等 |
\W |
匹配非大小寫字母和數字,也就是匹配大小寫字母和數字之外的其他任意字符或符號,如 a\Wc 可以匹配 a.c 、a#c 、a+c 等 |
實戰1:爬取ppt網頁一級頁面圖片
import re,requests
#參數設置
page_num=2#頁面數
headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}#請求頭信息,模擬瀏覽器進行請求
#開始爬取
for n in range(page_num):
url='http://www.1ppt.com/beijing/ppt_beijing_{}.html'.format(n+1)
response=requests.get(url,headers=headers)#發送請求
if response.status_code==200:
response.encoding=response.apparent_encoding#字符編碼設置爲網頁本來所屬編碼
html=response.text#獲取網頁代碼
pattern= re.compile(r'img src="(.*?jpg)" alt')#編譯正則表達式
image_url= pattern.findall(html)#解析圖片鏈接
for i,link in enumerate(image_url):
print('第{}頁第{}張圖片下載中......'.format(n+1,i+1))
resp=requests.get(link,headers=headers)#請求圖片鏈接
content=resp.content#獲取二進制內容
with open('./圖片/{}-{}.jpg'.format(n+1,i+1),'wb') as f:
f.write(content)#下載圖片
else:
print('請求失敗!')
實戰2:爬取ppt網頁二級頁面圖片
import requests,re
headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}#請求頭,模擬瀏覽器進行請求
page_num=2
for i in range(page_num):
url='http://www.1ppt.com/beijing/ppt_beijing_{}.html'.format(i+1)
print('第{}頁爬取中......'.format(i+1))
response=requests.get(url,headers=headers)#向一級網頁發送請求
if response.status_code==200:
response.encoding=response.apparent_encoding#字符編碼設置爲網頁本來所屬編碼
html=response.text#獲取網頁代碼
pattern=re.compile(r'<li> <a href="(.*?)" target="_blank">')#編譯正則表達式
url_sub=pattern.findall(html)#解析二級頁面鏈接
url_sub=['http://www.1ppt.com'+x for x in url_sub]#拼接成完整鏈接
for j,link in enumerate(url_sub):
print('第{}頁第{}個ppt爬取中......'.format(i+1,j+1))
resp=requests.get(link,headers=headers)#向二級網頁發送請求
if resp.status_code==200:
resp.encoding=resp.apparent_encoding#字符編碼設置爲網頁本來所屬編碼
html_sub=resp.text#獲取網頁代碼
pattern=re.compile(r'img src="(.*?)" width="700"')#編譯正則表達式
image_link=pattern.findall(html_sub)#解析圖片鏈接
for k,li in enumerate(image_link):
response_image=requests.get(li,headers=headers)#請求圖片鏈接
content=response_image.content#獲取圖片二進制內容
with open('./圖片/{}-{}-{}.jpg'.format(i+1,j+1,k+1),'wb') as f:
f.write(content)#下載圖片
else:
print('第{}頁第{}個ppt鏈接請求失敗!'.format(i+1,j+1))
else:
print('第{}頁一級頁面請求失敗!'.format(i+1))