一、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