利用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

猜你喜欢

转载自blog.csdn.net/qq_30852577/article/details/84654392