利用Lxml庫中xpath語法爬取異步加載網頁中圖片並存入mongodb

一、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)]依次構造

 

  1. 代碼實現
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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章