我之前写过一篇Python爬取百度图片,有兴趣的朋友可以去读一下,这次写的是爬取Bing的图片。
打开Bing图片,搜索关键词,开始分析页面,可以发现bing和百度一样都是下滑自动加载,百度默认一次加载30张,bing默认一次加载35张。
count是加载图片数,first是从第几张图片开始加载,直接连续请求解析网页就可以了
之前百度类似的代码也发过了,我们来说另一种方法,我们发现请求图片的时候是get请求,参数都在url里,我们可以尝试改变url来获取网页。在地址栏填入下面的网址:https://cn.bing.com/images/async?q=%E7%BE%8E%E5%A5%B3&first=0&count=35&relp=35&lostate=r&mmasync=1&dgState=x*175_y*848_h*199_c*1_i*106_r*0
可以看到网页只加载了35张图片,图片的数量还是由count控制,我们可以每次请求35张,下载35张,也可以根据自己的喜好改变。查看一下网页结构,找到每张图片的位置:
很好找,按照我们的思路先写一个保存图片的方法:
#从得到的图片链接下载图片,并保存
def SaveImage(link,InputData,count):
try:
time.sleep(0.2)
urllib.request.urlretrieve(link,'./'+InputData+'/'+str(count)+'.jpg')
except Exception :
time.sleep(1)
print("产生未知错误,放弃保存")
else:
print("图+1,已有" + str(count) + "张图")
加上错误处理是因为有些图片可能会因为各种各样的原因下载失败,防止遇到错误程序断掉,我们又不缺那一两张图片对吧。
time.sleep()是为了别让程序请求速度太快,防止被封ip
这里用到了urllib.request.urlretrieve,这个方法可以直接把网络上的图片存到指定的文件中,就不用先请求数据,再打开文件写入,关闭文件这么啰嗦的写法了
它一共有四个参数urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)
url:外部或者本地url
filename:指定了保存到本地的路径(如果未指定该参数,urllib会生成一个临时文件来保存数据)
reporthook:是一个回调函数,当连接上服务器、以及相应的数据块传输完毕的时候会触发该回调。我们可以利用这个回调函数来显示当前的下载进度。
data:指post到服务器的数据。该方法返回一个包含两个元素的元组(filename, headers),filename表示保存到本地的路径,header表示服务器的响应头。
然后再写获取链接的方法:
#找到图片的链接
def FindLink(PageNum,InputData,word):
for i in range(PageNum):
print(i)
try:
url = 'http://cn.bing.com/images/async?q={0}&first={1}&count=35&relp=35&lostate=r&mmasync=1&dgState=x*175_y*848_h*199_c*1_i*106_r*0'
#定义请求头
agent = {'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.165063 Safari/537.36 AppEngine-Google."}
page1 = urllib.request.Request(url.format(InputData, i*35+1), headers=agent)
page = urllib.request.urlopen(page1)
使用beautifulSoup进行解析网页
soup = BeautifulSoup(page.read(), 'html.parser')
#创建文件夹
if not os.path.exists("./" + word):
os.mkdir('./' + word)
for StepOne in soup.select('.mimg'):
link=StepOne.attrs['src']
count = len(os.listdir('./' + word)) + 1
SaveImage(link,word,count)
except:
print('URL OPENING ERROR !')
在请求时可以加上请求头模仿浏览器请求,也是为了被封ip。其它的也没什么说的,看代码都懂
最后整合:
if __name__=='__main__':
#输入需要加载的页数,每页35幅图像
PageNum = 100
#输入需要搜索的关键字
word='美女'
#UTF-8编码
InputData=urllib.parse.quote(word)
print(InputData)
FindLink(PageNum,InputData,word)