Python学习(20)--爬虫
在前几节我们一直在介绍正则表达式,今天我们就使用正则表达式写一个爬虫的小程序。首先什么是爬虫呢?爬虫就是按照一定的规则,自动地获取网络上的信息。下面我们将介绍一个通过爬虫获取网络图片的例子。其中,我们利用正则表达式匹配图片的网络地址,正则表达式其实就是我们爬虫用到的规则,主要有3个步骤去完成这个爬虫的小例子:
1.获取网页的源代码;
2.在网页源代码中匹配正则表达式,得到图片的网络地址;
3.通过网络地址下载图片。
(1)获取网页的源代码
当我们通过浏览器浏览网页时,都可以通过鼠标右击"查看源代码",来获取网页的源代码。如下是一个百度贴吧的网页以及网页的源代码截图:
其实爬虫和浏览器请求的原理是一样的,都是通过post或者get请求向服务器请求数据,服务器返回的都是网页源代码,只不过浏览器再一次将网页源代码"加工"成了网页界面。下面是获取百度贴吧一个网页(url="https://tieba.baidu.com/p/5193551629?red_tag=1816480244")源代码的例子:
- import urllib.request
- def getHtml(url):
- page=urllib.request.urlopen(url)#通过url向服务器请求数据,得到一个页面对象
- html=page.read()#页面对象通过read()方法获取网页源代码
- return html#返回网页源代码
- html=getHtml("https://tieba.baidu.com/p/5193551629?red_tag=1816480244")
- print(html)
如上,自定义函数getHtml(url)功能为获取url指定网页的源代码,模块urllib.request用于向服务器请求数据,通过注释可以很容易的了解以上代码的含义。运行结果如下:
如上通过控制台打印的就是url="https://tieba.baidu.com/p/5193551629?red_tag=1816480244"的网页源代码。
(2)获取图片的网络地址
打开url="https://tieba.baidu.com/p/5193551629?red_tag=1816480244"的网页可以看到,贴吧中有很多网友上传的壁纸图片,我们的任务就是将这些壁纸图片下载下来。下载图片前需要得到图片的网络地址, 而图片的网络地址就在之前第一步打印的网络源代码中,我们通过正则表达式匹配,以获取所有壁纸图片的网络地址。
在此贴吧网页中,除了有壁纸图片外,还有头像图片,广告图片等等。如下,
以上是百度贴吧各种图片的url,我们先分析下如何书写正则表达式来获取壁纸图片的url,首先在html中所有的图片都有一个src的属性来指示图片的源地址,如src="http://...",还可以看到壁纸图片的url中有一个sign的属性,这是与其他图片url的不同之处,最后所有壁纸图片都是以".jpg"结尾。所以,匹配url的正则表达式可以如下书写:r'src="(.+sign=.+\.jpg)"'。
如下代码为匹配壁纸图片url并返回所有壁纸url的例子:
- import re
- import urllib.request
- def getHtml(url):
- page=urllib.request.urlopen(url)#通过url向服务器请求数据,得到一个页面对象
- html=page.read()#页面对象通过read()方法得到网页源代码
- return html#返回网页源代码
- def getImageUrl(html):
- r1=r'src="(.+sign=.+\.jpg)"'# 壁纸url的正则表达式
- reObject=re.compile(r1)#对正则表达式编译,以提高匹配的速度
- imgList=re.findall(reObject,html.decode("utf-8"))#获取图片url列表
- return imgList
- html=getHtml("https://tieba.baidu.com/p/5193551629?red_tag=1816480244")
- imageList=getImageUrl(html)
- for url in imageList:
- print(url)
getHtml(url)与之前的重复,因为这里用到了获取html源代码的函数,所以一并粘贴到这里。自定义函数getImageUrl(html)的功能为通过正则匹配获取壁纸图片url列表,具体代码含义可以通过注释获取。值的注意的是,python中对字符的编码格式为Unicode编码,我们从服务器获取的html并不是unicode编码格式,而是"utf-8"编码格式,而正则匹配时是在字符串码中进行匹配的 ,所以需要把"utf-8"的字节码解码为unicode编码,如上html.decode("utf-8")就是将"utf-8"的字节码解码为Unicode码。获取的壁纸图片url的部分打印结果如下:
(3)下载图片
在获取壁纸图片的url后,通过url下载图片相对简单。直接调用的是,urllib.request模块的方法urlretrieve(url,filename),此方法的功能就是将远程服务器的数据下载到本地,url为要下载数据的网络地址,filename是为数据命名的名字。将所有的壁纸图片下载下来,我们的这个小项目就结束了。以下是这个爬虫程序的所有代码:
- import re
- import urllib.request
- def getHtml(url):
- page=urllib.request.urlopen(url)#通过url向服务器请求数据,得到一个页面对象
- html=page.read()#页面对象通过read()方法得到网页源代码
- return html#返回网页源代码
- def getImageUrl(html):
- r1=r'src="(.+sign=.+\.jpg)"'# 壁纸url的正则表达式
- reObject=re.compile(r1)#对正则表达式编译,以提高匹配的速度
- imgList=re.findall(reObject,html.decode("utf-8"))#获取图片url列表
- return imgList
- html=getHtml("https://tieba.baidu.com/p/5193551629?red_tag=1816480244")
- imageList=getImageUrl(html)
- for url in imageList:
- print(url)
- i=i+1
- urllib.request.urlretrieve(url,str(i)+".jpg")#下载url指定的壁纸图片
结果就是将所有的壁纸图片下载到了此程序所在的项目路径下。如下图:
这就是爬虫程序的完整过程