python按关键字爬取必应高清图片

通过查询前人的博客,发现必应可通过url按关键字查找图片:

https://www.bing.com/images/async?q=查询关键字&first=图片编号&count=图片数量&mmasync=1

 

基于该url,我写了一个爬虫类,实现了按关键字下载固定数量的必应高清图片。调用时只需要一条python语句即可(由于使用了线程池并发请求图片,所以下载速度较快,一分钟300张高清图片没问题):

# 关键词:电脑壁纸
# 需要的图片数量:100
# 图片保存路径:'E:\images'
BingImagesSpider('电脑美女壁纸', 100, 'E:\images').run()

 

爬虫类的源码如下:

import requests
from lxml import etree
import os
from multiprocessing.dummy import Pool
import json
from time import time

# 作用:按关键字、图片数量爬取必应图片,存放到指定路径。
# 使用方法:只需运行一条命令 BingImagesSpider('电脑美女壁纸', 200, 'E:\images').run()
class BingImagesSpider:
    thread_amount = 1000 # 线程池数量,线程池用于多IO请求,减少总的http请求时间
    per_page_images = 30 # 每页必应请求的图片数
    count = 0 # 图片计数
    success_count = 0
    # 忽略图片标签的一些字符
    ignore_chars = ['|', '.', ',', ',', '', '', '/', '@', ':', ':', ';', ';', '[', ']', '+']
    # 允许的图片类型
    image_types = ['bmp', 'jpg', 'png', 'tif', 'gif', 'pcx', 'tga', 'exif', 'fpx', 'svg', 'psd', 'cdr', 'pcd', 'dxf', 'ufo', 'eps', 'ai', 'raw', 'WMF', 'webp']
    # 请求头
    headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'}
    # 必应图片 url
    bing_image_url_pattern = 'https://www.bing.com/images/async?q={}&first={}&count={}&mmasync=1'

    def __init__(self, keyword, amount, path='./'):
        # keyword: 需爬取的关键字
        # amount: 需爬取的数量
        # path: 图片存放路径
        self.keyword = keyword
        self.amount = amount
        self.path = path
        self.thread_pool = Pool(self.thread_amount)

    def __del__(self):
        self.thread_pool.close()
        self.thread_pool.join()

    # 作用:从必应请求图片
    def request_homepage(self, url):
        # url: 必应图片页的 url
        return requests.get(url, headers=self.headers)

    # 作用:解析必应网页,得到所有图片的信息,封装到列表中返回
    # 每个图片的信息以字典对象存储,字典的键包括 image_title, image_type, image_md5, image_url
    def parse_homepage_response(self, response):
        # response: 必应网站的响应

        # 获取各图片信息所在的json格式字符串 m
        tree = etree.HTML(response.text)
        m_list = tree.xpath('//*[@class="imgpt"]/a/@m')

        # 对每个图片分别处理
        info_list = []
        for m in m_list:
            dic = json.loads(m)

            # 去除一些文件名中不允许的字符
            image_title = dic['t']
            for char in self.ignore_chars:
                image_title = image_title.replace(char, ' ')
            image_title = image_title.strip()

            # 有些图片的信息中不包含图片格式,该情况将图片设置为 jpg 格式
            image_type = dic['murl'].split('.')[-1]
            if image_type not in self.image_types:
                image_type = 'jpg'

            # 将每个图片的信息存为字典格式
            info = dict()
            info['image_title'] = image_title
            info['image_type'] = image_type
            info['image_md5'] = dic['md5']
            info['image_url'] = dic['murl']

            info_list.append(info)
        return info_list


    # 请求具体图片,保存到初始化时指定的路径
    def request_and_save_image(self, info):
        # info: 每个图片的信息,以字典对象存储。字典的键包括 image_title, image_type, image_md5, image_url
        filename = '{} {}.{}'.format(self.count, info['image_title'], info['image_type'])
        filepath = os.path.join(self.path, filename)

        try:
            # 请求图片
            response = requests.get(info['image_url'], headers=self.headers, timeout=1.5)
            # 保存图片
            with open(filepath, 'wb') as fp:
                fp.write(response.content)
            # 打印日志
            self.count += 1
            self.success_count += 1
            print('{}: saving {} done.'.format(self.count, filepath))

        except requests.exceptions.RequestException as e:
            self.count += 1
            print('{}: saving {}failed. url: {}'.format(self.count, filepath, info['image_url']))
            print('\t tip:', e)


    # 作用:图片信息的列表去重,去除重复的图片信息
    def deduplication(self, info_list):
        result = []

        # 用图片的 md5 做为唯一标识符
        md5_set = set()
        for info in info_list:
            if info['image_md5'] not in md5_set:
                result.append(info)
                md5_set.add(info['image_md5'])
        return result


    # 作用:运行爬虫,爬取图片
    def run(self):
        # 创建用于保存图片的目录
        if not os.path.exists(self.path):
            os.mkdir(self.path)

        # 根据关键词和需要的图片数量,生成将爬取的必应图片网页列表
        homepage_urls = []
        for i in range(int(self.amount/self.per_page_images * 1.5) + 1): # 由于有些图片会重复,故先请求1.5倍图片,豁免
            url = self.bing_image_url_pattern.format(self.keyword, i*self.per_page_images, self.per_page_images)
            homepage_urls.append(url)
        print('homepage_urls len {}'.format(len(homepage_urls)))

        # 通过线程池请求所有必应图片网页
        homepage_responses = self.thread_pool.map(self.request_homepage, homepage_urls)

        # 从必应网页解析所有图片的信息,每个图片包括 image_title, image_type, image_md5, image_url 等信息。
        info_list = []
        for response in homepage_responses:
            result = self.parse_homepage_response(response)
            info_list += result
        print('info amount before deduplication', len(info_list))

        # 删除重复的图片,避免重复下载
        info_list = self.deduplication(info_list)
        print('info amount after deduplication', len(info_list))
        info_list = info_list[ : self.amount]
        print('info amount after split', len(info_list))

        # 下载所有图片,并保存
        self.thread_pool.map(self.request_and_save_image, info_list)
        print('all done. {} successfully downloaded, {} failed.'.format(self.success_count, self.count - self.success_count))


if __name__ == '__main__':
    # 关键词:电脑壁纸
    # 需要的图片数量:100
    # 图片保存路径:'E:\images'
    start = time()
    BingImagesSpider('电脑壁纸', 100, 'E:\images').run()
    print(time() - start)

 

### 回答1: python根据关键字爬取微博相关信息是通过使用Python编写爬虫程序来实现的。首先,我们需要使用Python的requests库发送HTTP请求,模拟浏览器向微博网站发送查询请求。然后,我们可以使用正则表达式或者BeautifulSoup库来解析查询结果页面,提取出相关信息。 在爬取微博相关信息之前,我们需要登录微博账号,可以使用Python的Selenium库来模拟用户登录。登录成功后,我们就可以使用微博的搜索功能,根据关键字进行查询。 在搜索结果页面中,我们可以提取出每条微博的标题、内容、发布时间、点赞数、转发数、评论数等信息。这些信息可以帮助我们了解微博的热门话题、用户的关注度以及舆论走向等等。 在提取出每条微博的信息后,我们可以将这些信息保存到本地文件或者数据库中,以供后续分析使用。同时,我们也可以将这些信息进行可视化展示,比如绘制词云图、热点图等,以便更好地观察微博的相关信息。 需要注意的是,爬取微博相关信息要遵守网站的相关规则和法律法规。在编写爬虫程序时,我们应该设置合适的请求频率,避免给网站带来过大的负担。此外,我们也需要注意保护用户隐私,不要将用户敏感信息进行公开和滥用。 总之,Python提供了强大的库和工具,可以帮助我们根据关键字爬取微博相关信息,并进行进一步的分析和展示。这无疑为我们深入研究微博的热门话题、舆论动态等提供了有效的方式。 ### 回答2: Python根据关键字爬取微博相关信息的具体步骤如下所示。 首先,我们需要安装并导入相关的Python库,包括requests、BeautifulSoup和re。分别用于发送HTTP请求、解析HTML页面和进行正则表达式匹配。 接下来,我们需要使用微博提供的搜索API来获取相关关键字的搜索结果。可以通过向接口发送HTTP请求来获取搜索结果的JSON数据。 接着,我们需要解析获取到的JSON数据。可以使用Python的json库将JSON数据转换为Python字典。通过分析字典的结构,我们可以提取出需要的信息,比如微博的内容、用户名、发布时间等。 然后,我们可以将获取到的信息保存到本地文件或者数据库中,以便后续进行分析和处理。可以使用Python的文件操作函数或者数据库操作库实现数据的保存。 在爬取微博信息的过程中,需要注意一些问题。首先,要注意遵守微博的相关规定,尊重用户隐私,避免对用户造成不必要的困扰。其次,要处理好爬取过程中可能出现的网络故障和反爬措施,比如限制访问频率、验证码等。 最后,完成爬取微博相关信息的Python程序后,可以根据需要对数据进行分析和处理。可以使用Python的数据分析库,比如pandas、numpy和matplotlib等,进行数据清洗、统计和可视化分析。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值