学技术,看这里!Python爬虫网页图片详细步骤讲解

python

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

以下文章来源于腾讯云 ,作者 py3study

回车桌面图片爬取

今天我们就来爬爬这个网站

https://tu.enterdesk.com/

这个网站能爬的资源还是很多的,但我就写一个例子,其他的可以根据思路去写。

首先还是先来分析下这个网站的图片获取过程

 

我选择的是图库,先随便选择一个标签,我这选宠物吧

 

哟,我们再看看有没有翻页 开启F12(开发者工具)

用不习惯火狐,还是开谷歌来看吧

 

那么就访问看看?随便选取一个访问看看是不是能出图片 https://tu.enterdesk.com/chongwu/6.html

结果肯定是可以的啦

问题来了,现在怎么查看最后一页的页码是什么?一种是无限循环下去 直到 没有图片标签的时候报错,还有一种就是从源码中找出页码 那就得看有没有页码按钮 刚才滚轮比较快 现在慢一点 看有没有页码这些东西

 

这网站还是有页码的,那说明在html源码中能找到页码数

两种方法: F12工具选择元素

 

Ctrl+U走一波 源代码直接搜索

 

现在找到所有页码,接下来就是分析图片源地址了

 

选择目标图片看看是不是源地址 原图 打开一看其实不是

import requests

all_urls = [] # 我们拼接好的每一页链接

class Spider():

# 构造函数,初始化数据使用

def __init__(self, target_url, headers):

self.target_url = target_url

self.headers = headers

# 获取所有的想要抓取的URL

def getUrls(self):

#获取末页

response = requests.get(target_url % 1,headers=headers).text

html = BeautifulSoup(response,"html.parser")

res = html.find(class_="wrap no_a").attrs["href"] #找到末页的标签提取末页的链接

page_num = int(re.findall("(d+)",res)[0]) #正则匹配 页码数

global all_urls

# 循环得到拼接URL

for i in range(1, page_num + 1):

url = self.target_url % i

all_urls.append(url)

现在再点击进去图片里面 发现是原图了 这时再选择图片查看标签的图片链接

 

复制上图里面的链接 打开一看就是原图啦 看下图的链接 怎么那么熟悉?

 

对比下两个链接

import requests

all_urls = [] # 我们拼接好的每一页链接

class Spider():

# 构造函数,初始化数据使用

def __init__(self, target_url, headers):

self.target_url = target_url

self.headers = headers

# 获取所有的想要抓取的URL

def getUrls(self):

#获取末页

response = requests.get(target_url % 1,headers=headers).text

html = BeautifulSoup(response,"html.parser")

res = html.find(class_="wrap no_a").attrs["href"] #找到末页的标签提取末页的链接

page_num = int(re.findall("(d+)",res)[0]) #正则匹配 页码数

global all_urls

# 循环得到拼接URL

for i in range(1, page_num + 1):

url = self.target_url % i

all_urls.append(url)

略缩图 edpic_360_360 原图 edpic_source

这下整体思路就有啦,我们可以获取略缩图的链接将url进行重构,形成原图链接,然后再批量下载就好啦!

开始撸代码了!!!

第一个是 class Spider(): 我们声明了一个类,然后我们使用 def __init__去声明一个构造函数

import requests

all_urls = [] # 我们拼接好的每一页链接

class Spider():

# 构造函数,初始化数据使用

def __init__(self, target_url, headers):

self.target_url = target_url

self.headers = headers

# 获取所有的想要抓取的URL

def getUrls(self):

#获取末页

response = requests.get(target_url % 1,headers=headers).text

html = BeautifulSoup(response,"html.parser")

res = html.find(class_="wrap no_a").attrs["href"] #找到末页的标签提取末页的链接

page_num = int(re.findall("(d+)",res)[0]) #正则匹配 页码数

global all_urls

# 循环得到拼接URL

for i in range(1, page_num + 1):

url = self.target_url % i

all_urls.append(url)

分析怎么提取末页链接如下图:

 

这里我们采用多线程的方式爬取,引入下面几个模块

from bs4 import BeautifulSoup #解析html

import threading #多线程

import re #正则匹配

import time #时间

新增加一个全局的变量,而且是多线程操作,我们需要引入线程锁,避免资源同时写入出错。

all_img_urls = []       #所有图片链接

g_lock = threading.Lock() #初始化一个锁

声明一个Producer的类,负责提取图片链接,然后添加到 all_img_urls 这个全局变量中

class Producer(threading.Thread):

def run(self):

headers = {

"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0"

}

global all_urls

while len(all_urls) > 0:

g_lock.acquire() # 在访问all_urls的时候,需要使用锁机制

page_url = all_urls.pop(0) # 通过pop方法移除第一个元素,并且返回该值

g_lock.release() # 使用完成之后及时把锁给释放,方便其他线程使用

try:

print("分析" + page_url)

response = requests.get(page_url, headers=headers, timeout=3).text

html = BeautifulSoup(response,"html.parser")

pic_link = html.find_all(class_="egeli_pic_li")[:-1]

global all_img_urls

g_lock.acquire() # 这里还有一个锁

for i in pic_link:

link = i.find("img")["src"].replace("edpic_360_360","edpic_source")

all_img_urls.append(link)

g_lock.release() # 释放锁

# time.sleep(0.1)

except:

pass

线程锁,在上面的代码中,当我们操作all_urls.pop(0)的时候,我们是不希望其他线程对它进行同时操作的,否则会出现意外,所以我们使用g_lock.acquire()锁定资源,然后使用完成之后,记住一定要立马释放g_lock.release(),否则这个资源就一直被占用着,程序无法进行下去了。

if __name__ == "__main__":

headers = {

"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0"

}

target_url = "https://tu.enterdesk.com/chongwu/%d.html" # 图片集和列表规则

print("开始获取所有图片页链接!!!")

spider = Spider(target_url, headers)

spider.getUrls()

print("完成获取所有图片页,开始分析图片链接!!!")

threads = []

for x in range(10):

gain_link = Producer()

gain_link.start()

threads.append(gain_link)

# join 线程同步 主线程任务结束之后 进入阻塞状态 等待其他的子线程执行结束之后 主线程在终止

for tt in threads:

tt.join()

下面再定义一个DownPic类 用于下载图片

class DownPic(threading.Thread):

def run(self):

headers = {

"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0"

}

while True:

global all_img_urls

# 上锁

g_lock.acquire()

if len(all_img_urls) == 0: # 如果没有图片了,就解锁

# 不管什么情况,都要释放锁

g_lock.release()

break

else:

t = time.time()

down_time = str(round(t * 1000)) # 毫秒级时间戳

pic_name = "D: est"+ down_time + ".jpg"

pic = all_img_urls.pop(0)

g_lock.release()

response = requests.get(pic, headers=headers)

with open(pic_name, "wb") as f:

f.write(response.content)

f.close()

print(pic_name + " 已下载完成!!!")

可以看到利用了down_time = str(round(t * 1000)) 来生成毫秒级时间戳来命名图片 其实也可以获取图片的名称来命名 那就靠自己去写一个了

再从if __name__ == "__main__": 添加下面代码 用于开启多线程下载

print("分析图片链接完成,开始多线程下载!!!")

for x in range(20):

download = DownPic()

download.start()

整体流程就这么写完啦!run下代码

 

Tips:跑这个代码需要在D盘创建test文件夹 或者自己修改代码实现其他功能

附出完整代码:

import requests

from bs4 import BeautifulSoup #解析html

import threading #多线程

import re #正则匹配

import time #时间

all_urls = [] # 我们拼接好的每一页链接

all_img_urls = [] #所有图片链接

g_lock = threading.Lock() #初始化一个锁

class Spider():

# 构造函数,初始化数据使用

def __init__(self, target_url, headers):

self.target_url = target_url

self.headers = headers

# 获取所有的想要抓取的URL

def getUrls(self):

#获取末页

response = requests.get(target_url % 1,headers=headers).text

html = BeautifulSoup(response,"html.parser")

res = html.find(class_="wrap no_a").attrs["href"] #找到末页的标签提取末页的链接

page_num = int(re.findall("(d+)",res)[0]) #正则匹配 页码数

global all_urls

# 循环得到拼接URL

for i in range(1, page_num + 1):

url = self.target_url % i

all_urls.append(url)

#负责提取图片链接

class Producer(threading.Thread):

def run(self):

headers = {

"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0"

}

global all_urls

while len(all_urls) > 0:

g_lock.acquire() # 在访问all_urls的时候,需要使用锁机制

page_url = all_urls.pop(0) # 通过pop方法移除第一个元素,并且返回该值

g_lock.release() # 使用完成之后及时把锁给释放,方便其他线程使用

try:

print("分析" + page_url)

response = requests.get(page_url, headers=headers, timeout=3).text

html = BeautifulSoup(response,"html.parser")

pic_link = html.find_all(class_="egeli_pic_li")[:-1]

global all_img_urls

g_lock.acquire() # 这里还有一个锁

for i in pic_link:

link = i.find("img")["src"].replace("edpic_360_360","edpic_source")

all_img_urls.append(link)

g_lock.release() # 释放锁

# time.sleep(0.1)

except:

pass

class DownPic(threading.Thread):

def run(self):

headers = {

"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0"

}

while True:

global all_img_urls

# 上锁

g_lock.acquire()

if len(all_img_urls) == 0: # 如果没有图片了,就解锁

# 不管什么情况,都要释放锁

g_lock.release()

break

else:

t = time.time()

down_time = str(round(t * 1000)) # 毫秒级时间戳

pic_name = "D: est"+ down_time + ".jpg"

pic = all_img_urls.pop(0)

g_lock.release()

response = requests.get(pic, headers=headers)

with open(pic_name, "wb") as f:

f.write(response.content)

f.close()

print(pic_name + " 已下载完成!!!")

if __name__ == "__main__":

headers = {

"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0"

}

target_url = "https://tu.enterdesk.com/chongwu/%d.html" # 图片集和列表规则

print("开始获取所有图片页链接!!!")

spider = Spider(target_url, headers)

spider.getUrls()

print("完成获取所有图片页,开始分析图片链接!!!")

threads = []

for x in range(10):

gain_link = Producer()

gain_link.start()

threads.append(gain_link)

# join 线程同步 主线程任务结束之后 进入阻塞状态 等待其他的子线程执行结束之后 主线程在终止

for tt in threads:

tt.join()

print("分析图片链接完成,开始多线程下载!!!")

for x in range(20):

download = DownPic()

download.start()

以上是 学技术,看这里!Python爬虫网页图片详细步骤讲解 的全部内容, 来源链接: utcz.com/z/530563.html

回到顶部