静态页面抓取实战

静态页面抓取实战

目标:美图吧–风景类图片
在这里插入图片描述
有多个页面,分析各页面url:
在这里插入图片描述
页面序号随url最后一位数变换,第一页为1,第二页为2……找出规律后设定循环来进行循环访问个页面

右键点击图片检查:
在这里插入图片描述
每一张图片都有一个超链接(href),点击超链接进入
在这里插入图片描述
进入超链接页面即可得到展示图片的页面;同时每一组页面有多张图片,每张图片都有一个超链接,经过测试发现这个超链接(href)是同组图片中的下一涨图片的页面url;(src)就是图片的路径地址。src就是我的目标,通过得到这个src的值去访问图片路径地址,然后将图片下载下来

再次
在测试时发现一个问题,就是每一组的最后一张图片的href都是直接访问到另一个图片组的。为了逻辑处理上的方便,在进行爬取之前做个小处理: 在进入图片组页面之后,先获取这个图片组的图片张数,通过图片的数量控制在图片组中停留的次数,同时也避免因为通过最后一张图片的href直接进入到下一组图片,造成数据的混乱(原则上是可以直接通过每组图片最后一张图片的href直接进入到下一组图片的。但是弊端就是无法判断你是否把这一类别的数据获取完了)

至此这个静态页面抓取的思路就成型了。
下面直接挂上代码:

import requests
import os
from bs4 import BeautifulSoup
import re  

url = 'http://www.meituba.com/weimei/fjtp/list114{}.html'
# 因为url最后一个数是随页面序号变化的,因此用{}进行占位,在调用url时再传入页面序号去进行访问
ppho_url = 'http://www.meituba.com/weimei/fjtp/'
# 对于小网站可以不设headers,为了严谨一点,此案例加上headers
HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)'
                         ' Chrome/79.0.3941.4 Safari/537.36'}

# 解析器
def parser(url):
	# 建立请求 返回请求对象
    response = requests.get(url, headers=HEADERS)
    # 转码
    html = response.content.decode('utf-8')
    # 对转码后的网页信息进行解析(规范化)
    soup = BeautifulSoup(html, 'lxml')
    # 返回解析后的对象
    return soup

"""
pageNum为测试代码的参数,实际情况可以不设参数,直接通过条件判断对页面遍历到底,也可以通过参数指定要爬取的页数
"""
def crawling(pageNum):
	# 设定循环页面
    for i in range(1, pageNum + 1):
        response = parser(url.format(i))
        # 得到照片组的html并解析
        group_pho_htmls = response.find_all('a', target="_blank")
        original_group_pho_urls = []
        # 遍历照片组的解析html,并依次提取url并存储到列表中
        for group_pho_html in group_pho_htmls:
            original_group_pho_urls.append(group_pho_html["href"])
        # 得到的original_group_pho_urls有重复,为节省资源,进行一步去重
        group_pho_urls = []
        for original_group_pho_url in original_group_pho_urls:
            if original_group_pho_url not in group_pho_urls:
                group_pho_urls.append(original_group_pho_url)
        # 依次遍历每个图片组的路径并解析
        for group_pho_url in group_pho_urls:
            response = parser(group_pho_url)
            # 获取当前照片组的图片张数
            num_control = response.find_all('div', class_="pages")
            control_num = re.search('[0-9]', str(num_control))
            # 获取当前zu照片的路径
            pho_htmls = response.select('body > div.main21 > div.main > div.photo > a')
            pho_html = pho_htmls[0]["href"]
            # 由于一个组有多张照片  对pho_url进行拆分匹配
            pho_html = str(pho_html).split('_')[0]
            for i in range(1, int(control_num.group()) + 1):
                if i == 1:
                    pho_hhtml = ppho_url + '/' + str(pho_html) + '.html'
                    print(pho_hhtml)
                    response = parser(pho_hhtml)
                    pho_url_s = response.select('body > div.main21 > div.main > div.photo > a > img')
                    pho_url = pho_url_s[0]["src"]
                else:
                    pho_hhtml =ppho_url + '/' + str(pho_html) + '_' + str(i) + '.html'
                    print(pho_hhtml)
                    response = parser(pho_hhtml)
                    pho_url_s = response.select('body > div.main21 > div.main > div.photo > a > img')
                    pho_url = pho_url_s[0]["src"]
                # 拆分url 根据url命名文件
                dir_name = pho_url_s[0]["alt"]
                file_name = str(pho_url).split('/')[-1]
                # 将图片写入文件中
                try:
                    if not os.path.exists("./" + str(dir_name)):
                        os.mkdir("./" + str(dir_name))
                    if not os.path.exists("./" + str(dir_name) + '/' + file_name):
                        with open("./" + str(dir_name) + '/' + file_name, 'wb') as p:
                            p.write(requests.get(pho_url, headers=HEADERS).content)
                except :
                    print("发现了错误   跳过")
                i += 1
                # 如果已经获取到本组最后一张图片,就退出循环
                if i == int(control_num.group()) + 1:
                    break


if __name__ == '__main__':
    crawling(2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

royallucky(视觉方向)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值