不到20行的代码用python爬取图片
1.先把代码放出来
import requests,os
from bs4 import BeautifulSoup as bea
if not os.path.exists('images'):
os.makedirs('images')
def save():
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0"}
for x in range(2):
link = 'https://www.youmeitu.com/weimeitupian/list_'+str(x+1)+'.html'
r = requests.get(link, headers=headers)
soup = bea(r.text, 'lxml')
for y in range(30):
xxx = soup.select('div.TypeList:nth-child(5) > ul:nth-child(1) > li:nth-child(' + str(y + 1)
+ ') > a:nth-child(1) > img:nth-child(1)')
true_url = 'https://www.youmeitu.com' + str(xxx)[24:-16]
f = requests.get(true_url)
print(xxx, y)
with open("study1/images/" + str(x+1)+'__' + str(y + 1) + "'.jpg", "wb") as code:
code.write(f.content)
test=save()
2.需要用到requests和bs4
3.请求头
我用的浏览器是火狐浏览器,进入一个网站,我这里随便用百度找了一个图片网站:https://www.youmeitu.com/,鼠标右键选择查看元素选择“网络”,点击第一项,右边出现消息头,里面的请求头里面就有User-Agent这一项,是我们需要的
4.CSS选择器
在首页中点击“唯美图片”,发现网址变为“https://www.youmeitu.com/weimeitupian/”,先别急,下拉选择第2页发现网址变为“https://www.youmeitu.com/weimeitupian/list_2.html”,所以不同页数的规律是link=“https://www.youmeitu.com/weimeitupian/list_”+str(x+1)+".html"
,知道了这一点我们就可以一次下载多页图片了。发现一页一共有30张图,所以要30次内循环。
然后用BeautifulSoup对网页进行解析,做法很简单。先右击网页中我们需要下载的图片选择查看元素,然后对下方选中的项右击复制CSS选择器,这一步很重要。比如我们选择的是第一张图片,那么我们粘贴得到div.TypeList:nth-child(5) > ul:nth-child(1) > li:nth-child(1) > a:nth-child(1) > img:nth-child(1)
,但看一个看不出规律,我们再复制粘贴第二张图片的CSS选择器得到div.TypeList:nth-child(5) > ul:nth-child(1) > li:nth-child(2) > a:nth-child(1) > img:nth-child(1)
,这样规律就很明显了,只有其中的一个数字变了其他的都没变,通用的字符串可以确定为'div.TypeList:nth-child(5) > ul:nth-child(1) > li:nth-child(' + str(y + 1)+ ') > a:nth-child(1) > img:nth-child(1)'
。
5.图片下载
link = 'https://www.youmeitu.com/weimeitupian/list_'+str(x+1)+'.html'
r = requests.get(link, headers=headers)
soup = bea(r.text, 'lxml')
print(soup.select('div.TypeList:nth-child(5) > ul:nth-child(1) > li:nth-child(1) > a:nth-child(1) > img:nth-child(1)')
发现输出结果为
[<img height="270" src="/Upload/20191231/1577778669589059.jpg?x-oss-process=image/resize,m_fill,w_180,h_270" width="180"/>]
我们直接右击第一张图片选择复制图像地址为https://www.youmeitu.com/Upload/20191231/1577778669589059.jpg?x-oss-process=image/resize,m_fill,w_180,h_270
,所以我们需要的下载地址为https://www.youmeitu.com+src
,这里我们需要操作一下字符串,数一下或者多试几次就会发现我们需要的字符串位置是[24:-16]。有了它我们的下载地址也就确定了,下载可以有很多种办法下载,我这里直接用with语句,简单的对图片命名就行了。这样一切就大公告成了,是不是很简单。
但是发现下载的很慢,所以想办法改进了一下,可以多线程。更多信息可以参考《python网络爬虫–从入门到实践》,作者是唐松,写得很不错的。
import requests,os
from bs4 import BeautifulSoup as bea
from threading import Thread
if not os.path.exists('images'):
os.makedirs('images')
class mythread(Thread):
def __init__(self,name,soup,x):
Thread.__init__(self)
self.name=name
self.soup=soup
self.x=x
def run(self):
print('starting'+self.name)
func(self.soup,self.x)
def func(soup,x): # 实时更新
for y in range(30):
xxx = soup.select('div.TypeList:nth-child(5) > ul:nth-child(1) > li:nth-child(' + str(y + 1)
+ ') > a:nth-child(1) > img:nth-child(1)')
true_url = 'https://www.youmeitu.com' + str(xxx)[24:-16]
f = requests.get(true_url)
print(xxx, x, y)
with open("images/" + str(x + 1) + '__' + str(y + 1) + "'.jpg", "wb") as code:
code.write(f.content)
def save():
thread=[]
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0"}
for x in range(1,5):
link = 'https://www.youmeitu.com/weimeitupian/list_'+str(x+1)+'.html'
r = requests.get(link, headers=headers)
soup = bea(r.text, 'lxml')
threads=mythread('thread-'+str(x+1),soup,x)
threads.start()
thread.append(threads)
for t in thread:
t.join()
print('Exiting Main Thread')
save()