php网页抓取图片(桌面壁纸电脑桌面壁纸高清壁纸大全下载(二):将图片下载到本地有了图片链接 )
优采云 发布时间: 2021-12-28 04:22php网页抓取图片(桌面壁纸电脑桌面壁纸高清壁纸大全下载(二):将图片下载到本地有了图片链接
)
一:目标站点信息
卞桌面网站为:桌面壁纸,电脑桌面壁纸,高清壁纸,下载,桌面背景图片,卞桌面
2:目标站点分析
(1): 构建页面的 URL 列表
我们需要做的是抓取网站上给定数量页面的图片,所以我们首先需要观察每个页面的链接之间的关系,然后构建一个需要抓取的URL列表。
第一页的链接:http://www.netbian.com/
第二页的链接:http://www.netbian.com/index_2.htm
可以看到第二页后面的页面链接只是和后面的数字不同,我们可以写一个简单的代码来获取页面的url列表
# 页面链接的初始化列表
page_links_list=['http://www.netbian.com/']
#获取爬取的页数和页面链接
pages = int(input('请输入你想爬取的页数:'))
if pages > 1:
for page in range(2, pages + 1):
url = 'http://www.netbian.com/index_' + str(page) + '.htm'
page_links_list.append(url)
else:
page_links_list=page_links_list
print(page_links_list)
请输入你想爬取的页数:5
['http://www.netbian.com/', 'http://www.netbian.com/index_2.htm', 'http://www.netbian.com/index_3.htm', 'http://www.netbian.com/index_4.htm', 'http://www.netbian.com/index_5.htm']
(2): 获取一个页面上所有图片的链接
我们已经获取了所有页面的链接,但是还没有获取到每张图片的链接,那么接下来我们要做的就是获取一个页面中所有图片的链接。这里以第一页为例,获取每张图片的链接,其他页面类似。
首先右击页面->查看元素,然后点击查看器左侧的小光标,然后将鼠标放在随机一张图片上,这样就可以定位到图片的代码位置;我们可以知道每个页面有18张图片。接下来,我们需要使用标签来定位图片在页面上的具体位置。如下图所示,我们使用 div.list li a img 来精确定位 18 个 img 标签。img 标签收录
我们需要的图片链接。
接下来我们以第一页为例,获取每张图片的链接。
#python3 -m pip install bs4
#python3 -m pip install lxml
import requests
from bs4 import BeautifulSoup
# 页面链接的初始化列表
url='http://www.netbian.com/'
# 图片链接列表
img_links_list = []
#获取img标签,在获取图片链接
html = requests.get(url).content.decode('gbk')
soup = BeautifulSoup(html, 'lxml')
imgs = soup.select("div.list li a img")
for img in imgs:
img_link = img['src']
img_links_list.append(img_link)
print(img_links_list)
print(len(img_links_list))
['http://img.netbian.com/file/2019/0817/smalle213d95e54c5b4fb355b710a473292ea1566035585.jpg', 'http://img.netbian.com/file/2019/0817/small15ca224d7*敏*感*词*c119affe2cfd2d811862e1566035332.jpg', 'http://img.netbian.com/file/2018/1225/604a688cd6f79161236e6250189bc25b.jpg', 'http://img.netbian.com/file/2019/0817/smallab7249d18e67c9336109e3bedc094f381566034907.jpg', 'http://img.netbian.com/file/2019/0817/small5816e940e6957f7db5e499de9978bda41566031298.jpg', 'http://img.netbian.com/file/2019/0817/smalladda3febb072e9103f8f06f27dcb19c21566031139.jpg', 'http://img.netbian.com/file/2019/0817/small0e9f43492debe6dc2ce7a3e6c*敏*感*词*8c1ad1566030965.jpg', 'http://img.netbian.com/file/2019/0817/smallcfd5b4c6fa10ffcbcdcc8b1b9e6db91a1566030209.jpg', 'http://img.netbian.com/file/2019/0817/smalld1f07e215f0da059b44d27623ec6fa8f1566029835.jpg', 'http://img.netbian.com/file/2019/0817/small1674b7b97714672be3165bd31de418eb1566014363.jpg', 'http://img.netbian.com/file/2019/0814/small1a5c2fe49dec02929f219d0bdb680e9c1565786931.jpg', 'http://img.netbian.com/file/2019/0814/smalle333c0a8e9fe18324d793ce7258abbbf1565786718.jpg', 'http://img.netbian.com/file/2019/0814/smallb0c9494b4042ac9c9d25b6e4243facfd1565786402.jpg', 'http://img.netbian.com/file/2019/0814/small19dfd078dd820bb1598129bbe4542eff1565786204.jpg', 'http://img.netbian.com/file/2019/0808/smallea41cb48c796ffd3020514994fc3e8391565274057.jpg', 'http://img.netbian.com/file/2019/0808/small3998*敏*感*词*0805ea6811d81b7c57d8d235fc1565273792.jpg', 'http://img.netbian.com/file/2019/0808/smallb505448b1318dbb2820dcb212eb39e191565273639.jpg', 'http://img.netbian.com/file/2019/0808/small0f04af422502a40b6c8dc19d53d1f3481565273554.jpg']
18
(3): 下载图片到本地
有了图片链接后,我们需要将图片下载到本地,这里以第一张图片为例进行下载
import urllib.request
url='http://img.netbian.com/file/2019/0817/smalle213d95e54c5b4fb355b710a473292ea1566035585.jpg'
urllib.request.urlretrieve(url, filename='test.jpg')
(4): 一个简单的获取图片的爬虫
结合以上三部分,构建页面的url列表,获取一个页面中的所有图片链接,将图片下载到本地。构建一个完整但效率低下的爬虫。
import requests
from bs4 import BeautifulSoup
import lxml
import urllib
import os
import time
#获取图片并下载到本地
def GetImages(url):
html=requests.get(url, timeout = 2).content.decode('gbk')
soup=BeautifulSoup(html,'lxml')
imgs=soup.select("div.list li a img")
for img in imgs:
link=img['src']
display=link.split('/')[-1]
print('正在下载:',display)
filename='./images/'+display
urllib.request.urlretrieve(link,filename)
#获取爬取的页数,返回链接数
def GetUrls(page_links_list):
pages = int(input('请输入你想爬取的页数:'))
if pages > 1:
for page in range(2, pages + 1):
url = 'http://www.netbian.com/index_' + str(page) + '.htm'
page_links_list.append(url)
else:
page_links_list=page_links_list
if __name__ == '__main__':
page_links_list=['http://www.netbian.com/']
GetUrls(page_links_list)
os.mkdir('./images')
print("开始下载图片!!!")
start = time.time()
for url in page_links_list:
GetImages(url)
print('图片下载成功!!!')
end = time.time() - start
print('消耗时间为:', end)
请输入你想爬取的页数:5
开始下载图片!!!
正在下载: smalle213d95e54c5b4fb355b710a473292ea1566035585.jpg
正在下载: small15ca224d7*敏*感*词*c119affe2cfd2d811862e1566035332.jpg
正在下载: 604a688cd6f79161236e6250189bc25b.jpg
正在下载: smallab7249d18e67c9336109e3bedc094f381566034907.jpg
正在下载: small5816e940e6957f7db5e499de9978bda41566031298.jpg
正在下载: smalladda3febb072e9103f8f06f27dcb19c21566031139.jpg
正在下载: small0e9f43492debe6dc2ce7a3e6c*敏*感*词*8c1ad1566030965.jpg
正在下载: smallcfd5b4c6fa10ffcbcdcc8b1b9e6db91a1566030209.jpg
。。。。。。
图片下载成功!!!
消耗时间为: 21.575999975204468
上面这部分代码完全可以运行,但是效率不高,因为是下载图片,需要排队一一下载。因此,为了解决这个问题,下面的代码使用多线程来实现图片的抓取和下载。
(5)使用Python多线程抓取图片并下载到本地
对于多线程,我们使用 Python 自带的线程模块。我们使用称为生产者和消费者的模型。生产者专门用于从每个页面中获取图片的下载链接并将其存储在全局列表中。消费者专门从这个全局列表中提取图像链接以供下载。
需要注意的是,在多线程中使用全局变量需要使用锁来保证数据的一致性。
import urllib
import threading
from bs4 import BeautifulSoup
import requests
import os
import time
import lxml
# 页面链接的初始化列表
page_links_list=['http://www.netbian.com/']
# 图片链接列表
img_links_list = []
#获取爬取的页数和页面链接
def GetUrls(page_links_list):
pages = int(input('请输入你想爬取的页数:'))
if pages > 1:
for page in range(2, pages + 1):
url = 'http://www.netbian.com/index_' + str(page) + '.htm'
page_links_list.append(url)
else:
page_links_list=page_links_list
#初始化锁,创建一把锁
*敏*感*词*=threading.Lock()
#生产者,负责从每个页面中获取图片的链接
class Producer(threading.Thread):
def run(self):
while len(page_links_list)>0:
#上锁
*敏*感*词*.acquire()
#默认取出列表中的最后一个元素
page_url=page_links_list.pop()
#释放锁
*敏*感*词*.release()
#获取img标签
html = requests.get(page_url).content.decode('gbk')
soup = BeautifulSoup(html, 'lxml')
imgs = soup.select("div.list li a img")
#加锁3
*敏*感*词*.acquire()
for img in imgs:
img_link = img['src']
img_links_list.append(img_link)
#释放锁
*敏*感*词*.release()
#print(len(img_links_list))
#消费者,负责从获取的图片链接中下载图片
class Consumer(threading.Thread,):
def run(self):
print("%s is running"%threading.current_thread())
while True:
#print(len(img_links_list))
#上锁
*敏*感*词*.acquire()
if len(img_links_list)==0:
#不管什么情况,都要释放锁
*敏*感*词*.release()
continue
else:
img_url=img_links_list.pop()
#print(img_links_list)
*敏*感*词*.release()
filename=img_url.split('/')[-1]
print('正在下载:', filename)
path = './images/'+filename
urllib.request.urlretrieve(img_url, filename=path)
if len(img_links_list)==0:
end=time.time()
print("消耗的时间为:", (end - start))
exit()
if __name__ == '__main__':
GetUrls(page_links_list)
os.mkdir('./images')
start=time.time()
# 5个生产者线程,去从页面中爬取图片链接
for x in range(5):
Producer().start()
# 10个消费者线程,去从中提取下载链接,然后下载
for x in range(10):
Consumer().start()
请输入你想爬取的页数:5
is running
is running
is running
is running
is running
is running
is running
is running
is running
is running
正在下载: small9e75d6ac9506efe1d87e96062791fb261564149099.jpg
正在下载: small02961cac5e02a901b77779eaed43c6f91564156941.jpg
正在下载: small117c84b2f427c981bf33184c1c5*敏*感*词*bb91564193581.jpg
正在下载: smallfedb420af6f753512c169021587982621564455847.jpg
正在下载: small14d3739bf11dd92055abb56e3f792d3f1564456102.jpg
正在下载: smallaf755644af7d114d4cbf36fbe0e84d0c1564456347.jpg
正在下载: small9f7af6d0e2372a4d9e536d8ea9f*敏*感*词*0341564456537.jpg
。。。。。。
消耗的时间为: 1.635000228881836 #分别是10个进程结束的时间
消耗的时间为: 1.6419999599456787
消耗的时间为: 1.6560001373291016
消耗的时间为: 1.684000015258789
消耗的时间为: 1.7009999752044678
消耗的时间为: 1.7030000686645508
消耗的时间为: 1.7060000896453857
消耗的时间为: 1.7139999866485596
消耗的时间为: 1.7350001335144043
消耗的时间为: 1.748000144958496