小白也能看懂的python爬虫,从零开始爬彼岸图网壁纸美图
你是否有过以下烦恼:
- 想找壁纸却找不到
- 找到的壁纸清晰度都不高?
- 下载图片太麻烦?
现在,你将可以用简简单单二十行代码解决这一切烦恼,还不赶快跟我行动起来?
首先来看一下效果图吧
好了,那我们现在开始吧,let’s go!!!
首先我们打开彼岸壁纸的网址:! http://www.netbian.com/mei/index.htm
对于爬虫,我们拿到一个网站先看看源代码,看看是否可以直接获取
显然,我们想要的图片源代码里面都有,哈哈,这不就好办了吗
既然如此,那我们看看它是怎么换页的,我们点到其他页观察其url,
第二页:http://www.netbian.com/mei/index_2.htm
第三页: http://www.netbian.com/mei/index_3.htm
很明显,我们知道后面的数字就是彼岸图网的翻页规律,那第一页是不是! http://www.netbian.com/mei/index.htm_1呢,我们不得而知,访问看看
结果告诉我们,并不是!!!!虽然直接跳转是可以访问的,但是在浏览器输入却不行,那是因为浏览器自动跳转到 http://www.netbian.com/mei/index.htm了
因此我们得单独判断第一页的
我们首先写下爬虫最基本的一些代码
base_url = 'http://www.netbian.com/mei/index.htm' # 第一页url
# 一共有165页,因此我们可以将所有的url先列出来,以便更好的操作
list = [f'http://www.netbian.com/mei/index_{i + 2}.htm' for i in range(164)] #这是列表推导式,循环164次,然后就可以生成164个url了,也就是除了第一页的所有页面
list.insert(0, base_url) # 为了方便,我们将第一页的url加进其他页的列表中的第一个位置
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36'
} #这是请求头,在浏览器中就可以找到它
首先我们对第一页的爬取进行分析
既然我们想要的东西网页源代码中都有,那我们可以直接获取
打开开发者工具:键盘上按下F12或者在页面空白处单机鼠标右键–>检查
然后进入到如图所示界面,先后点击1和2,发现定位到点击图片的位置处,通过前端代码我们发现图片都在ul标签中,也就是所有的li标签,因此我们点开li标签就可以看到图片的地址了
然后我们根据img标签写xpath表达式://div[@class=‘list’]/ul/li/a/img/@src
通过xpath我们就能得到所有图片的 url 了,同样,我们保存图片需要对图片命名,因此我们获取到图片的标题://div[@class=‘list’]/ul/li/a/img/@alt
代码如下
res=requests.get(url,headers=headers)
print(res.status_code)
html = etree.HTML(res.content.decode('gbk'))
hrefs = html.xpath("//div[@class='list']/ul/li/a/img/@src") # 获取链接
titles = html.xpath("//div[@class='list']/ul/li/a/img/@alt") # 获取标题
得到了图片的链接我们就可以快乐的下载图片啦
for href, title in zip(hrefs, titles): # 这个是对链接和标题进行遍历,得到每一个标题和链接
with open(f"./图片/{title}" + '.jpg','wb')as f: # 这就是保存图片咯,如果你想保存在某个地方,只需要把那个地址与"./图片"替换就可以了,如果你就想保存在这儿,你应该在你写代码的同路径下创建一个名字为图片的文件夹
response=requests.get(href,headers=headers).content
f.write(response)
print(title, "------下载完成------")
就这样,我们就完成了165页图片的下载了,是不是很神奇,你的烦恼都没了吧
完整代码如下
import requests
from lxml import etree
from concurrent.futures import ThreadPoolExecutor # 这是加快代码运行速度的
def download(url): # 写一个函数封装代码
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36'
} #请求头
res=requests.get(url,headers=headers) #向网站发送get请求
html = etree.HTML(res.content.decode('gbk')) #将字符串转换成element类型
hrefs = html.xpath("//div[@class='list']/ul/li/a/img/@src") # 获取图片链接
titles = html.xpath("//div[@class='list']/ul/li/a/img/@alt") # 获取图片标题
for href, title in zip(hrefs, titles):
with open(f"./图片/{title}" + '.jpg','wb')as f: # wb是二进制文件写入
response=requests.get(href,headers=headers).content #图片保存用二进制形式
f.write(response)
print(title, "------下载完成------")
if __name__ == '__main__':
base_url = 'http://www.netbian.com/mei/index.htm'
list = [f'http://www.netbian.com/mei/index_{i + 2}.htm' for i in range(164)]
list.insert(0, base_url)
with ThreadPoolExecutor() as pool: # 这是线程池,可以加快代码的运行速度
[pool.submit(download,url) for url in list] # 从list中遍历取出所有的url然后下载
当然,你可能还会有以下问题
- 随便下载了几张图片就再也下不了了
- 下载的图片打不开
这些都是因为IP被封了,所以就访问不了网站了
因此,为了解决这个问题,我们可以使用代理,也就是用别人的IP,而python使用代理的方法也很简单,只需要增加几行代码即可
proxies = {
'http': 'http://' # 省略号处就是IP啦:IP:端口
'https': 'https://......'
}
而IP我们可以去哪里获取呢?我们可以网上搜索免费IP即可找到很多IP网站,找到免费的就行了,当然免费的能用的只是少数,但为了学习,免费的足够了
使用IP的方法有很多,为了偷懒,这里直接把所有的IP写在代码中,关键代码如下
A=['125.65.16.63:4278','1.70.249.56:4212','111.199.129.47:4212','221.11.234.251:4220','117.94.158.92:4236','117.26.195.72:4213','27.190.82.112:4278','183.32.224.214:4246','117.34.192.155:4210','113.239.159.62:4245']
i=random.choice(A) # 在A中随机选择一个IP
proxies = {
'http': 'http://'+i,
'https': 'https://'+i
}
# 发送get请求时加上代理
response=requests.get(href,proxies=proxies,headers=headers).content
A存储了要使用的IP,然后每次随机从A里面取一个使用
使用代理后的完整代码如下,当然没多大区别
import requests
from lxml import etree
from concurrent.futures import ThreadPoolExecutor
import random
def download(url):
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36'
}
A=['125.65.16.63:4278','1.70.249.56:4212','111.199.129.47:4212','221.11.234.251:4220','117.94.158.92:4236','117.26.195.72:4213','27.190.82.112:4278','183.32.224.214:4246','117.34.192.155:4210','113.239.159.62:4245']
i=random.choice(A)
proxies = {
'http': 'http://'+i,
'https': 'https://'+i
}
res=requests.get(url,headers=headers)
print(res.status_code)
html = etree.HTML(res.content.decode('gbk'))
hrefs = html.xpath("//div[@class='list']/ul/li/a/img/@src")
titles = html.xpath("//div[@class='list']/ul/li/a/img/@alt")
for href, title in zip(hrefs, titles):
with open(f"./图片/{title}" + '.jpg','wb')as f:
response=requests.get(href,proxies=proxies,headers=headers).content
f.write(response)
print(title, "------下载完成------")
if __name__ == '__main__':
base_url = 'http://www.netbian.com/mei/index.htm'
list = [f'http://www.netbian.com/mei/index_{i + 2}.htm' for i in range(164)]
list.insert(0, base_url)
with ThreadPoolExecutor() as pool:
[pool.submit(download,url) for url in list]
到现在了,是不是没什么问题了?
什么?你找不到IP在哪里?
下面以芝麻代理为例,芝麻代理每天有20个免费的IP,亲测质量也是挺好的,用于学习也够了
- 首先打开芝麻代理首页,注册登录,然后点击HTTP代理
- 点击获取API
- 选择免费的IP
- 然后选择要提取的数量,其他保持默认就行,当然你也可以更改
- 然后点击生成API链接,在下面的打开链接中选择一个打开,你就可以看到你提取的IP啦
- 最后将这些 IP换在A列表中就可以无限的快乐啦