首页 > 其他分享 >[案例]贴吧爬取并获取图片

[案例]贴吧爬取并获取图片

时间:2023-07-17 11:25:23浏览次数:37  
标签:name 获取 url self title 帖子 案例 data 图片

import os
import random
import re
import sys
import time
import urllib.parse

import requests
from lxml import etree
from lxml.etree import _Element


class TiebaSpider(object):

    BASE_DIR = os.path.dirname(__file__)

    def __init__(self, url, name):
        self.url = url
        self.name = name
        self.header = {
            "Host": "tieba.baidu.com",
            # "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/104.0",
            "User-Agent": "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)"
        }

        # 创建目录,用于保存图片
        if not os.path.exists(self.name):
            print(f"创建目录:{self.name}")
            os.mkdir(os.path.join(self.BASE_DIR, self.name))

    def get_data(self, pagesize):
        """获取响应体"""
        # 带了UA去请求和不带UA去请求返回的内容不一样,证明网站都是有检测UA的,以前做易语言POST都做过了....
        resp = requests.get(f"{self.url}{urllib.parse.quote(self.name)}&ie=utf-8&pn={pagesize * 50}",
                            headers=self.header)
        return resp.content

    def parse_data(self, data):
        """
        1、帖子列表://div[@class="threadlist_title pull_left j_th_tit"]
            如果item下能获取到i元素就是置顶帖: ./i[@title="置顶"]   置顶帖排除出去。
            
            每个帖子的url:
                ./a/@href
                
            每个帖子title:./a
            
        2、再次访问每个帖子的url,获取其中的图片并下载(只获取帖子第一页的,就不写这么多了...)

        """
        etree_html: _Element = etree.HTML(data.decode())

        tiezi_elements = etree_html.xpath(
            '//div[@class="threadlist_title pull_left j_th_tit"] | //div[@class="threadlist_title pull_left j_th_tit "]')

        clist = []
        for element in tiezi_elements:
            title = element.xpath("./a/text()")[0]
            url = element.xpath("./a/@href")[0]
            clist.append({
                "title": title,
                "url": url
            })
        return clist

    def parse_detail(self, data):
        """遍历列表中的每个帖子,发起请求,获取帖子中图片地址"""
        for item in data:
            # 补充完整的url
            full_url = "https://tieba.baidu.com" + item["url"]
            print(f"正在获取帖子【{item.get('title')}】中的图片...")
            # 发送请求
            resp = requests.get(full_url, headers=self.header)
            content = resp.content.decode()
            # 初始化tree
            etree_html: _Element = etree.HTML(content)
            # 获取图片
            src_list = etree_html.xpath('//img[@class="BDE_Image"]/@src')
            print(src_list)
            print("*" * 150)

            # 以帖子名创建子目录,调用保存图片的方法保存图片
            tiezi_dir = os.path.join(self.BASE_DIR, os.path.join(self.name, item["title"]))
            try:
                os.mkdir(tiezi_dir)
            except:
                pass
            print(tiezi_dir + "已经存在,跳过创建目录。")
            self.save_pics(tiezi_dir, src_list)

    def save_pics(self, dirname, pic_list):
        """
        :param dirname: 帖子的目录path
        :param pic_list: 帖子中的图片url列表
        :return:
        """
        print(dirname, pic_list)

        for pic_url in pic_list:
            # 通过正则拿到原来的图片名
            # 用replace是因为它的sign=69f653d42559252da3171d0c049a032c/f0d931adcbef7609fb3928516bdda3cc7dd99ef8.jpg
            # 所以就替换掉/就i算了
            pic_name = re.search(r'sign=(.*)\?tbpicau=', pic_url).group(1).replace("/", "")
            # 图片属于二进制数据,用b模式
            with open(os.path.join(dirname, pic_name), "wb") as f:
                # 贴吧图片下载需要指定另外的请求头,不然会提示403
                f.write(requests.get(pic_url, headers={
                    "Host": "tiebapic.baidu.com",
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0",
                }).content)
                f.flush()

    def run(self, size):
        """这里就没有用xpath拿到下一页了,没啥意思,就这样循环几次就行了"""
        for i in range(1, size + 1):
            print(f"正在读取【{self.name}】贴吧的第{i}页数据....")
            data = self.get_data(i)

            # 获取页中的帖子url地址
            parse_data = self.parse_data(data)
            # 解析并获取每个帖子中的图片地址并保存
            self.parse_detail(parse_data)
            # 延迟一下,防止被反扒检测到太快了...
            time.sleep(random.randint(1, 5))


if __name__ == '__main__':

    """获取指定贴吧的每个帖子中的图片并保存"""

    if len(sys.argv) >= 3:
        name = sys.argv[1]
        pages = int(sys.argv[2])
    else:
        pages = 1
        name = "海贼王"

    url = "https://tieba.baidu.com/f?kw="

    TiebaSpider(url, name).run(pages)

标签:name,获取,url,self,title,帖子,案例,data,图片
From: https://www.cnblogs.com/juelian/p/17559519.html

相关文章

  • IOS开发-实现图片缓存优化性能
    在Objective-C中,可以这么实现图片的本地缓存:1.创建一个用于存储图片的缓存文件夹;2.根据图片URL构建缓存文件名;3.检查缓存路径是否存在,如果存在直接读取缓存图片;4.不存在则从网络下载图片;5.保存图片到缓存,以名称cacheFilename;6.以后再加载同一个URL的图片,就直接从......
  • 利于puppeteer获取网络资源的直链
    背景比如我想使用curl或者页面按钮点击直接下载个网盘资源,那就会出现问题。因为目前各大网盘给的分享链接都是一个页面,而且大部分还都做了防盗机制,你无法简单的获取真实下载连接!但是我们可以利用puppeteer来做到!蓝奏云lanzou-helper.jsimport{sleep}from'./index.js'......
  • 初识GaussDB——GaussDB的发展历程、部署方式和企业案例
    初识GaussDB——GaussDB的发展历程、部署方式和企业案例姜殿斌2020-02-1734311.GaussDB的命名和品牌GaussDB的热点话题名字的由来:GaussDB是华为数据库产品品牌名,致敬数学家高斯(Gauss)GaussDB的品类:GaussDBT和GaussDBAGaussDBT的里程碑发布时间:2019年5......
  • redis 怎么通过key的获取时间范围查询
    Redis通过Key的时间范围查询方案Redis是一种高性能的内存键值存储数据库,它提供了丰富的数据结构和功能。在实际应用中,我们经常需要根据key的时间范围查询数据,以满足不同的业务需求。本文将介绍如何使用Redis进行时间范围查询,并提供一些代码示例来解决具体的问题。问题描述假设我......
  • redis 如何解决并发之前获取数据都是空
    Redis如何解决并发之前获取数据都是空在并发场景中,我们有时会遇到一个问题:多个线程在同一时刻获取数据,但是数据还没有被写入到数据库中,此时获取到的数据都是空。为了解决这个问题,我们可以利用Redis提供的锁机制和发布/订阅功能来实现。Redis锁机制Redis提供了一种简单而有......
  • r语言主成分分析案例
    R语言主成分分析案例什么是主成分分析?主成分分析(PrincipalComponentAnalysis,简称PCA)是一种常用的数据降维技术,它可以将高维数据映射到低维空间中,并保持样本之间的相对几何关系。通过主成分分析,我们可以发现数据中的主要特征,并剔除无关变量,从而简化数据分析过程。主成分分析的......
  • 采集极验4滑块验证码图片数据
    在网络安全领域,验证码是一种常见的用于验证用户身份或防止恶意机器人攻击的技术。而极验4滑块验证码作为一种广泛应用的验证码形式,其具有较高的安全性和防御能力。本文将以获取极验4滑块验证码图片数据为主题,介绍相关技术和方法。一、极验4滑块验证码简介极验4滑块验证码是一种......
  • Java图片去噪
    Java图片去噪介绍图片去噪是一种常见的图像处理技术,可以帮助我们减少图片中的噪点,提高图像的质量和清晰度。在Java中,我们可以利用一些图像处理库来实现图片去噪的功能。本文将为你介绍如何使用Java实现图片去噪的步骤和相应的代码。流程下面是实现“Java图片去噪”的流程:步......
  • Mybatis获取与实践
    Mybatis如何获得MybatisMavenhttps://mvnrepository.com/artifact/org.mybatis/mybatis<!--https://mvnrepository.com/artifact/org.mybatis/mybatis--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis<......
  • pytorch使用(二)python读取图片各点灰度值or怎么读、转换灰度图
    python读取图片各点灰度值方法一:在使用OpenCV读取图片的同时将图片转换为灰度图:img=cv2.imread(imgfile,cv2.IMREAD_GRAYSCALE)print("cv2.imread(imgfile,cv2.IMREAD_GRAYSCALE)结果如下:")print('大小:{}'.format(img.shape))print("类型:%s"%type(img))print(img)......