在我们写文章(博客、公众号、自媒体)
的时候,常常觉得自己的文章有些老土,这很大程度是因为配图
没有选好。本文将和大家分享一个实用爬虫案例!
笔者也是遇到相同的情况,顺便解决其中一个案例,给大家一些技术上的参考和借鉴!
并且,我们搜图片如果去百度,会遇到两种情况:非高清
或者带水印
。这都是我们所忌讳的东西。笔者此次通过图虫创意抓起高清小图,虽然不是大图,但是在火热的移动端阅读上是足够的!
分析
废话说完了,我们开始分析怎么样才能获取这样的图片呢。
我们的理想状态就是一个网页,我们的目标网页,把图片<img src="xxxxxx">
直接放到html中。我们的爬虫可以直接解析。这种情况,就像你写的博客,个人网站的图片一样,简单嵌入。
或者就是通过后台ajax传输图片地址引用。我们不清楚
是否这样!
但事实这种肯定会被理想破灭,因为不可能!他以图片为核心业务
,要你注册,购买等等,怎么可能就这么容易
的嵌入进入被你找到。
首先打开网页,检查图片,发现它的网页图片来源不唯一。有两个主要域名ice
和wel
,并且后面的编号还不唯一,但是可以尝试发现相同域名不同后缀的图片地址结果相同
!(例如icweiliimg9
和icweiliimg/
效果相同)。
我们发现原来这个搜索url会变化,但是这个查看网页源代码发现并没有我们想要的图片地址。那么我们肯定知道它要么从ajax渲染
,或者就藏在js中进行混淆或者加密
。我们发现这个xhr中并没有想要的数据,并且他其实藏在js中。其实这个可以猜想到的,因为它的url既然跟着变化那么返回的数据肯定是有区别
的。
那么分析就到这里,剩下就是python爬虫的模拟和解析了。
前面说到已经知道它的数据源,我们用python编写爬虫需要进行模拟。经过测试发现它需要进行一些验证,其中包过cookie
的wluuid
字段(只验证存在,不验证正确性)。
那么我们编写一段代码就能拿到网页html。但是问题来了。数据藏在js里面啊!!!
我们只能用正则进行套了!
对于这个js,我们通过js=soup.select('script') js=js[4]
即可获取。
对于有用数据,只能正则截取。
pattern = re.compile(r'window.hits = (\[)(.*)(\])')
va = pattern.search(str(js)).group(2)#解析js内容
但是这个类似json的串用,
拼接我们无法直接使用spilt分组分开,但是我们可以从}
全部替换成},,
那么就三个,,,
我们就可以分割而不影响其他json串内,
;split之后每组都满足json串格式
,直接转成json取值即可!
那么剩下拿到url直接构造url然后下载图片即可!
图片下载:
爬虫方面
其他
代码与总结
通过上述分析:编写爬虫:
import requests
from urllib import parse
from bs4 import BeautifulSoup
import re
import json
header = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
'Cookie': 'wluuid=66; ',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
'Accept-encoding': 'gzip, deflate, br',
'Accept-language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'max-age=0',
'connection': 'keep-alive'
, 'Host': 'stock.tuchong.com',
'Upgrade-Insecure-Requests': '1'
}
def mkdir(path):
import os# 引入模块
path = path.strip()# 去除首位空格
path = path.rstrip("\\") # 去除尾部 \ 符号
isExists = os.path.exists(path) # 判断路径是否存在 # 存在 True # 不存在 False
if not isExists: # 判断结果
os.makedirs(path)# 如果不存在则创建目录 # 创建目录操作函数
return True#print (path + ' 创建成功')
else:
# 如果目录存在则不创建,并提示目录已存在
#print(path + ' 目录已存在')
return False
def downloadimage(imageid,imgname):
url = 'https://weiliicimg9.pstatp.com/weili/ms/'+str(imageid)+'.webp'
url2 = 'https://icweiliimg9.pstatp.com/weili/ms/'+str(imageid)+'.webp'
b=False
r = requests.get(url)
print(r.status_code)
if(r.status_code!=200):
r=requests.get(url2)
with open(imgname+'.jpg', 'wb') as f:
f.write(r.content)
print(imgname+" 下载成功")
def getText(text):
texturl = parse.quote(text)
url="https://stock.tuchong.com/search?term="+texturl+"&use=0"
req=requests.get(url,headers=header)
soup=BeautifulSoup(req.text,'lxml')
js=soup.select('script')
js=js[4]
print(js)
pattern = re.compile(r'window.hits = (\[)(.*)(\])')
va = pattern.search(str(js)).group(2)#解析js内容
print(va)
va = va.replace('{', '{').replace('}', '},,')
print(va)
va = va.split(',,,')
print(va)
index = 1
for data in va:
try:
dict = json.loads(data)
print(dict)
imgname='img/'+text+'/'+dict['title']+str(index)
index+=1
mkdir('img/'+text)
imgid=dict['imageId']
downloadimage(imgid,imgname)
except Exception as e:
print(e)
if __name__ == '__main__':
getText(text=input('输入关键词:'))
测试结果:
打开文件夹:
发现nice!你只需要输入关键词即可实现自动下载,虽然是小图,但是效果不错!