手持Python,斗图不输!

本文以抓取“斗图啦”(http://www.doutula.com/)中的图片为例来介绍如何使用python和正则表达式完成最基本的爬虫和文件下载工作。

进入网站后,点击最新表情,并点击第二页,网页的url(http://www.doutula.com/photo/list/?page=2)同样发生了变化。不难发现,此网页的请求方式为最简单的get请求。

 

Python资源共享群:484031800

下面,我们将使用requests、re、os库来实现图片的抓取与下载。

一、导入python标准库

这里我们将用到三个标准库,os用来创建文件夹并更改缺省路径;requests用来抓取网页源代码;re用来提取源代码中我们需要的信息。

  •  
import os import reimport requests

 

二、创建文件夹并更改缺省路径

  •  
os.mkdir(r"D:/斗图")  #在D盘创建“斗图”文件夹,如果文件夹存在则会报错。os.chdir(r"D:/斗图")   #更改缺省路径到"D:/斗图"。os.getcwd()  #查看缺省路径是否已经更改。

三、构建headers,抓取网页源代码

首先,我们构建一个名为headers的字典,并传给requests.get()中的headers参数,requests将该参数作为请求报文的首部字段编制报文,字典headers中可以传入请求头的部分信息以防止网站反爬。那么,headers字典中的参数是从哪里得到的呢?参考爬虫俱乐部往期推文《一起来揪出网页真实链接!》,找到网页的一些请求头:即下图的Headers。

 

 

 

 

 

我们使用几个重要参数构建字典,程序如下:

  •  
headers = {        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',        'Host': 'www.doutula.com'        }

我们在这里设定字典中的两个key分别是User-Agent、Host,当然,请求头中的其他参数也可根据需求添加到字典中。接下来,使用requests.get()方法抓取网页源代码,程序如下:

  •  
response = requests.get("http://www.doutula.com/photo/list/?page=1",headers = headers)print(response.text)text = response.text

requests.get()方法中的第一个参数是url,此参数是必须传入的一个参数。此外,此方法中还有一些其他参数,例如:headers,传入请求头信息;proxies,传入代理地址;params,传入get请求的参数,例如“http://www.doutula.com/photo/list/?page=1”,get请求方式如果以“?”携带参数,可将参数“page=1”构建成字典传给params,此时requests.get()中传入的url则变成“http://www.doutula.com/photo/list/”。

 

打印网页源代码,发现python为我们解析出的网页源代码无乱码,可直接使用text变量来接收网页源代码。

四、使用正则表达式提取信息
	部分网页源代码如下:

 

 

 

 

 

“data-original”属性的值就是图片的地址,而p标签中存放的则为图片名称,我们的目的就是利用图片的url将图片下载下来,将下载下来的文件名设定为图片原本的文件名,因此我们需要提取url和图片名。

首先使用re.findall方法将图片的url和名称提取出来,此方法第一个需要传入的参数为正则表达式,第二个参数为目标字符串,第三个参数re.S的作用是使正则表达式将目标字符串作为一个整体,将“\n”当做一个普通的字符加入到这个字符串中,使“.“能够匹配换行符,而无须在匹配之前将目标字符串中的空字符剔除。

  •  
imgs_url_name = re.findall('data-original="(.*?)".*?<p.*?>(.*?)</p>',text,re.S)
	re.findall方法可直接将子表达式中包含的内容提取出来。
  •  
print(imgs_url_name)len(imgs_url_name)
	结果如下:

 

 

 

 

 

可以发现,findall方法返回一个列表,列表中的每一个元素都是一个元组,元组中的每条信息就是子表达式匹配到的内容。关于re库更详细的用法可参考爬虫俱乐部往期推文《Python标准库re:正则表达式》。

五、下载图片

这一步需将上边获取到的url和图片名称使用切片提取出来并使用requests.get()方法和文件操作的方法将图片下载到本地。程序如下:

  •  
for img in imgs_url_name:   #img是包含图片url和名称的元组    name = img[1]        #提取图片名称    name = re.sub(r'[\??\.,。!! /]','',name)    #将图片名称中的一些不适合作为文件名的符号剔除。    #print(name)    url = img[0]      #提取图片url    #print(url)suffix = os.path.splitext(url)[1]    #提取图片后缀

os.path.splitext()方法可分离文件名与扩展名,默认返回元组。例如,“http://img.doutula.com/production/uploads/image//2019/07/01/20190701929023_ZBfzXo.jpg“可分离成”http://img.doutula.com/production/uploads/image//2019/07/01/20190701929023_ZBfzXo“和“.jpg”.

  •  
  #print(suffix)    filename = name + suffix      #使用图片名称和后缀构造文件名print(filename)#获取每张图片的源代码,并将其以二进制形式写入文件。    r = requests.get(url)            with open(filename,"wb") as fp :        fp.write(r.content)

 

 

 

 

 

有了这些图片,你就是斗图界的专家啦!

以 上是爬取单个页面的程序,如果我们想爬取多个页面,只需要对页码循环,并更改url中参数page的 值即可,完整程序如下:

 

 

  •  
import os import reimport requests
os.mkdir(r"D:/斗图")os.chdir(r"D:/斗图")os.getcwd()
headers = {        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',        'Host': 'www.doutula.com'        }for page_num in range(1,5) :    response = requests.get("http://www.doutula.com/photo/list/?page={}".format(page_num),headers = headers)        print(response.text)    text = response.text        imgs_url_name = re.findall('data-original="(.*?)".*?<p.*?>(.*?)</p>',text,re.S)    print(imgs_url_name)    len(imgs_url_name)        for img in imgs_url_name:        name = img[1]        name = re.sub(r'[\??\.,。!!/ ]','',name)        print(name)        url = img[0]        print(url)        suffix = os.path.splitext(url)[1]        print(suffix)        filename = name + suffix        print(filename)        r = requests.get(url)        with open(filename,"wb") as fp :            fp.write(r.content)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值