一、Lxml介紹
lxml是python的一個解析庫,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高。
XPath,全稱XML Path Language,即XML路徑語言,它是一門在XML文檔中查找信息的語言,它最初是用來搜尋XML文檔的,但是它同樣適用於HTML文檔的搜索。
XPath的選擇功能十分強大,它提供了非常簡明的路徑選擇表達式,另外,它還提供了超過100個內建函數,用於字符串、數值、時間的匹配以及節點、序列的處理等,幾乎所有我們想要定位的節點,都可以用XPath來選擇。
安裝比較簡單:pip3 install lxml
在anaconda環境中安裝後無法識別可以參考 https://mp.csdn.net/postedit/84098562
二、示例
以爬取https://www.pexels.com/網站中“phone”圖片爲例,不難發現,每次爬取的圖片並不多,而網站是通過下滑來不斷刷新圖片的,說明該網站使用了異步加載技術(AJAX)。Chrome瀏覽器中右鍵“檢查”,點擊“Network”-“XHR”-“Headers”,然後下來主頁面圖片,發現Request URL有幾個變化。
第一頁
第二頁
發現page=2,page=3依次變化,因此可能每一頁區別在page,經測試,發現https://www.pexels.com/search/phone/?page=1對於第一頁顯示不變,https://www.pexels.com/search/phone/?page=2顯示的確實是第二頁,因此構造url可以通過urls = [url_path + content + '/?page={}'.format(i) for i in range(1,num)]依次構造
- 代碼實現
from bs4 import BeautifulSoup
import requests
import os
import pymongo
import gridfs
client = pymongo.MongoClient('localhost',27017)
db = client['fileDB']
file_table = db['fileTable']
headers ={
'accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36 QIHU 360SE'}
def get_pic_urls(url_path,num,content):
urls = [url_path + content + '/?page={}'.format(i) for i in range(1,num)]
urlList = []
for url in urls:
wb_data = requests.get(url,headers=headers)
soup = BeautifulSoup(wb_data.text,'lxml')
imgs = soup.select('article > a > img')
if imgs==[]:
pass
else:
for img in imgs:
photoUrl = img.get('src')
urlList.append(photoUrl)
return urlList
def mongo2disk(path):
if os.path.exists(path): #創建磁盤存儲路徑
pass
else:
os.makedirs(path)
fs = gridfs.GridFS(db, 'fileTable')
i = 0
for file in fs.find():
bdata = file.read()
filename=fs.list()[i]
fp = open(path +filename , 'wb')
i = i + 1
fp.write(bdata)
fp.close()
def store2mongo(urlList):#將mongodb中數據存入文件系統
count=0
fs = gridfs.GridFS(db, 'fileTable')
for item in urlList:
filename=str(item.split('?')[0][-10:])
query = {'filename': filename}
if fs.exists(query):
print('已經存在該文件')
else:
data = requests.get(item.split('?')[0],headers=headers)
fs.put(data.content,filename=filename) #存入mongodb
count += 1
print('已經下載', count, '張圖片')
if __name__=='__main__':
url_path = 'https://www.pexels.com/search/'
num=50#爬取頁數
content = input('請輸入你要下載的圖片英文類型:')#爬取主題
path = 'f://photo//' + content + '/' #圖片存儲入磁盤路徑
urlList=get_pic_urls(url_path,num,content)
store2mongo(urlList)
mongo2disk(path)
2.代碼解析
get_pic_urls()函數實現對“phone”搜索頁的頁面構造,並獲取每幅圖片的url地址。
store2mongo()函數實現對圖片下載並存儲入mongodb。
mongo2disk()函數實現對mongodb中存儲的二進制圖片信息下載至本地磁盤。
經檢查對比發現,下載的圖片與網頁上圖片一致,代碼實現正確
gridfs使用請參考https://mp.csdn.net/postedit/84645693