python爬虫实战,下载某可翻页网站的图片

使用库:

  • requests
  • OS(用于图片保存)
  • lxml(用于使用xpath提取图片链接)

思路:

  1. 通过xpath获取图片链接
  2. 下载图片

目标网址:(由于网站性质,将域名改为xxx)

https://xxx.com/t/17652068

网站结构分析:
网站为论坛格式,其中,“17652068”为帖子标识号,每页约有10张左右希望提取的图片,论坛翻页通过改变链接实现,如:

第一页:https://xxx.com/t/17652068?page=1
第二页:https://xxx.com/t/17652068?page=2

如果页码越界,将会提供一个只有一张图片的相同网页。

图片存储格式:
利用F12审查元素得到,图片位于如下位置:
python爬虫实战,下载某可翻页网站的图片_第1张图片
因为不太会xpath语法,这里直接通过改写HarlanHong的文章中提供的xpath语句(主要是修改了图片所存在的块(html应该是这么叫)的名称),写出:

$x("//div[@class='h-threads-img-box']/a/@href")
$x("//div[@class='h-threads-img-box']/a/img/@data-src")

并检验无误:
python爬虫实战,下载某可翻页网站的图片_第2张图片
然后可以得到收集所有图片地址的函数:

def get_links(num, page = 1, end_page = None, links = []):
    while 1:
        url = 'https://xxx.com/t/{}?page={}'.format(num, page)
        r = requests.get(url).content  # 导入lxml库和html.fromStringh函数来解析html
        sel = html.fromstring(r)  # 提取h1标签,text()获取该标签下的文本
        link = sel.xpath("//div[@class='h-threads-img-box']/a/@href")
        links += link[1:]
        print('{}的第{}页已完成'.format(num,page))
        if len(link) == 1: 
            print('到达末页第{}页,爬虫停止'.format(page))
            return links
        if end_page and page == end_page:
            print('到达设置的爬取终点第{}页,爬虫停止'.format(page+end_page))
            return links
        page += 1

这里参考了younggege的代码。
然后是下载部分,这里使用了站里iprotn的部分代码:

def pic_down(root, links):
    for link in links:
        path = root + '\\' + link.split('/')[-1]  # 获取img的文件名
        print(path)
        try:
            if not os.path.exists(root):  # 判断是否存在文件并下载img
                os.mkdir(root)
            if not os.path.exists(path):
                read = requests.get(link)
                with open(path, "wb")as f:
                    f.write(read.content)
                    f.close()
                    print("文件保存成功!")
            else:
                print("文件已存在!")
        except:
            print("文件爬取失败!")

将两个函数打包,形成最终程序:

import requests
import os
from lxml import html  # 调用html.fromString函数解析html源代码

def get_links(num, page = 1, end_page = None, links = []):
    while 1:
        url = 'https://adnmb2.com/t/{}?page={}'.format(num, page)
        r = requests.get(url).content  # 导入lxml库和html.fromStringh函数来解析html
        sel = html.fromstring(r)  # 提取h1标签,text()获取该标签下的文本
        link = sel.xpath("//div[@class='h-threads-img-box']/a/@href")
        links += link[1:]
        print('{}的第{}页已完成'.format(num,page))
        if len(link) == 1:
            print('到达末页第{}页,爬虫停止'.format(page))
            return links
        if end_page and page == end_page:
            print('到达设置的爬取终点第{}页,爬虫停止'.format(page+end_page))
            return links
        page += 1


def pic_down(root, links):
    for link in links:
        path = root + '\\' + link.split('/')[-1]  # 获取img的文件名
        print(path)
        try:
            if not os.path.exists(root):  # 判断是否存在文件并下载img
                os.mkdir(root)
            if not os.path.exists(path):
                read = requests.get(link)
                with open(path, "wb")as f:
                    f.write(read.content)
                    f.close()
                    print("文件保存成功!")
            else:
                print("文件已存在!")
        except:
            print("文件爬取失败!")


def down_pic_of_ad(num,root,start_page = 1 ,end_page = None, judge='N'):
    while judge not in ['y','Y']:
        judge = input("你将把{}的图片下载到{},确认请输入Y,输错请Cc重来".format(num,root))
    links = get_links(num,page=start_page,end_page=end_page)
    print('爬取完成,开始下载')
    pic_down(root,links)
    print('完成')

输入示例:

down_pic_of_ad(17652068,r'E:\17652068',1,5)

可以提高修改的方向:

  1. 提取链接的同时下载,提高效率
  2. 多线程下载
  3. 使用代理ip避免屏蔽

你可能感兴趣的:(python爬虫实战,下载某可翻页网站的图片)