python关键词爬取bing【必应images】高清大图

本人python小白一个,为了入门,决定还是直接上个小项目-->爬虫。废话不多说,先剖析一下必应的响应页面。打开firefox,到必应里搜索关键词“欧阳娜娜”,再查看请求头发现是这样的:

搜索

这里url中对汉字进行了转码,类似encodeURL的处理,python中可以做如下处理:

import urllib

key="欧阳娜娜"
new = new = urllib.parse.quote(key)

这样,我们就可以自定义关键词了,想爬什么图片就爬什么图片。下一步就是确定url中的参数,为了程序中使用统一的url,我对网页进行多次请求,得到多个url然后找出哪些参数是我们需要关心的,方法是就是简单的滚动窗口,看到下一页就点击下一页,这个过程中需要记录下url及参数设置,方便分析

url格式

最终确定了下面的url。确定了url之后,就可以得到一页包含count数的图片了,但是这些图片都还只是缩略图,而我们的目标是原图,就是bing从哪里找来的,我们就去哪里找。

header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.2107.204 Safari/537.36'
}

url = "https://cn.bing.com/images/async?q={0}&first={1}&count={2}&scenario=ImageBasicHover&datsrc=N_I&layout=ColumnBased&mmasync=1&dgState=c*9_y*2226s2180s2072s2043s2292s2295s2079s2203s2094_i*71_w*198&IG=0D6AD6CBAF43430EA716510A4754C951&SFX={3}&iid=images.5599"

 接下来就是找到真正的原图所在地。打开浏览器,查看源代码,发现这里有好多url,而图片的onclick方法传递的是href,观察发现href也不是我们最终的目标,因为:虽然我们能通过https://cn.bing.com+href得到一个url但是这个也是bing加载原图之后创建的一个UI,为了用户体验而已,但我们是机器呀,我们是不需要UI的(狗头保命)

找到原图url

 为了保险起见,我们到这个UI里找找原图的踪迹,果然功夫不负有心人,murl的值就是原图的url!

原图URL就是murl的值

接下来就是写代码准备开工了!先定义全局变量如下

import sys
import os
import urllib
from bs4 import BeautifulSoup
import re
import time

header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.2107.204 Safari/537.36'
    }

url = "https://cn.bing.com/images/async?q={0}&first={1}&count={2}&scenario=ImageBasicHover&datsrc=N_I&layout=ColumnBased&mmasync=1&dgState=c*9_y*2226s2180s2072s2043s2292s2295s2079s2203s2094_i*71_w*198&IG=0D6AD6CBAF43430EA716510A4754C951&SFX={3}&iid=images.5599"

#需要爬取的图片关键词
name="欧阳娜娜"
#本地存储路径
path = "D:\\"+name 

然后是获取列表页

'''获取缩略图列表页'''
def getStartHtml(url,key,first,loadNum,sfx):
    page = urllib.request.Request(url.format(key,first,loadNum,sfx),headers = header)
    html = urllib.request.urlopen(page)
    return html

 然后获取这一页的原图url并统计个数。需要注意的是,由于html文本的原因,被浏览器解析时& = &这是html里所涉及到的一点点东西,在处理页面时我们需要注意。

'''从缩略图列表页中找到原图的url,并返回这一页的图片数量'''
def findImgUrlFromHtml(html,rule,url,key,first,loadNum,sfx,count):
    soup = BeautifulSoup(html,"lxml")
    link_list = soup.find_all("a", class_="iusc")
    url = []
    for link in link_list:
        result = re.search(rule, str(link))
        #将字符串"amp;"删除
        url = result.group(0)
        #组装完整url
        url = url[8:len(url)]
        #打开高清图片网址
        getImage(url,count)
        count+=1
    #完成一页,继续加载下一页
    return count

再将图片存下来

'''从原图url中将原图保存到本地'''
def getImage(url,count):
    try:
        time.sleep(0.5)
        urllib.request.urlretrieve(url,path+'\\'+str(count+1)+'.jpg')
    except Exception :
        time.sleep(1)
        print("产生了一点点错误,跳过...")
    else:
        print("图片+1,成功保存 " + str(count+1) + " 张图")

最后是main函数。因为没有找到bing是怎样对资源加载完毕后用户仍然在请求做处理,暂时还没有找到停止扒图的方法,于是我只给它限制了一个数,只扒取这么多,如果有人知道怎么判断停止欢迎给我留言哟,嘻嘻嘻!

def main():
    key = urllib.parse.quote(name)
    first = 1
    loadNum = 35
    sfx = 1
    count = 0
    #正则表达式
    rule = re.compile(r"\"murl\"\:\"http\S[^\"]+")
    #图片保存路径
    if not os.path.exists(path):
        os.makedirs(path)
    #目前还没有找到停止的办法,还请知道的朋友告知
    while count<500:
        html = getStartHtml(url,key,first,loadNum,sfx)
        count = findImgUrlFromHtml(html,rule,url,key,first,loadNum,sfx,count)
        first = count+1
        sfx += 1

if __name__ == '__main__':
    main()

最后再来一张成果展示吧

成果!

最后再来完整的代码吧

import sys
import os
import urllib
from bs4 import BeautifulSoup
import re
import time

header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.2107.204 Safari/537.36'
    }

url = "https://cn.bing.com/images/async?q={0}&first={1}&count={2}&scenario=ImageBasicHover&datsrc=N_I&layout=ColumnBased&mmasync=1&dgState=c*9_y*2226s2180s2072s2043s2292s2295s2079s2203s2094_i*71_w*198&IG=0D6AD6CBAF43430EA716510A4754C951&SFX={3}&iid=images.5599"

#需要爬取的图片关键词
name="欧阳娜娜"
#本地存储路径
path = "D:\\"+name 

'''获取缩略图列表页'''
def getStartHtml(url,key,first,loadNum,sfx):
    page = urllib.request.Request(url.format(key,first,loadNum,sfx),headers = header)
    html = urllib.request.urlopen(page)
    return html

'''从缩略图列表页中找到原图的url,并返回这一页的图片数量'''
def findImgUrlFromHtml(html,rule,url,key,first,loadNum,sfx,count):
    soup = BeautifulSoup(html,"lxml")
    link_list = soup.find_all("a", class_="iusc")
    url = []
    for link in link_list:
        result = re.search(rule, str(link))
        #将字符串"amp;"删除
        url = result.group(0)
        #组装完整url
        url = url[8:len(url)]
        #打开高清图片网址
        getImage(url,count)
        count+=1
    #完成一页,继续加载下一页
    return count

'''从原图url中将原图保存到本地'''
def getImage(url,count):
    try:
        time.sleep(0.5)
        urllib.request.urlretrieve(url,path+'\\'+str(count+1)+'.jpg')
    except Exception :
        time.sleep(1)
        print("产生了一点点错误,跳过...")
    else:
        print("图片+1,成功保存 " + str(count+1) + " 张图")

def main():
    key = urllib.parse.quote(name)
    first = 1
    loadNum = 35
    sfx = 1
    count = 0
    #正则表达式
    rule = re.compile(r"\"murl\"\:\"http\S[^\"]+")
    #图片保存路径
    if not os.path.exists(path):
        os.makedirs(path)
    #抓500张好了
    while count<500:
        html = getStartHtml(url,key,first,loadNum,sfx)
        count += findImgUrlFromHtml(html,rule,url,key,first,loadNum,sfx,count)
        first = count+1
        sfx += 1

if __name__ == '__main__':
    main()

 

  • 16
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值