一.HTML标记语言基础
要从网页中抽取数据出来,那么了解HTML标记语言是很重要的,但是这个系列的博客并不是要专门讲HTML的,所以,不会讲过多的HTML的细节.对于很熟悉HTML的人就不说啦,对于不熟悉HTML语言的同学,这里推荐一个教程,精简,方便查阅.HTML 教程
也就是说,之后的所有操作都是默认大家有HTML的一些知识的.
二.BeautifulSoup常见API
对于一个Beautiful对象,经常用到的两个函数是find()
和findAll()
函数,下面讲解一下这两个函数的原型和一些用法。
Beautiful Soup官方文档
Ⅰ.find_all()
函数原型:
find_all( name , attrs , recursive , text , **kwargs
)
作用:find_all()
方法搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件.
参数:
- name:查找所有名字为
name
的tag,字符串对象会被自动忽略掉. - attrs:用python字典封装一个标签的若干属性和这些属性分别对应的值。
- recursive:布尔变量,一般来说,
find_all()
方法会检索当前tag的所有子孙结点。因为recursive默认是True
接下里讲例子,这个例子使用的网页是《python数据采集》这本书提供的网页。我觉得还可以,就用这个网页作为例子。
War and Peace
网页的源代码是这个样子:
例一:name参数使用
import urllib.request
import urllib.parse
import urllib.error
import urllib.response
from bs4 import BeautifulSoup
request=urllib.request.Request(url="http://www.pythonscraping.com/pages/warandpeace.html")
response=urllib.request.urlopen(request)
bs=BeautifulSoup(response.read())
namelist=bs.find_all(name="h1")
print(namelist)
print("type of name list:",type(namelist))
在这个例子里面,传递的名字(标签)就只有h1,namelist=bs.find_all(name="h1")
然后这个语句的作用就是在当前的tag(这里的tag是html)下面找所有的(子标签以及不停递归下去,名字满足就行)h1
标签的元素,返回默认是存在一个列表里面的,意味着你能够查找多个tag。比如上面这个就返回了源码的h1.
例二.attrs的使用
我们现在想从这个网页上面找到所有绿色字体的部分,应该怎么找呢?首先看一下粗略看一下网站的源码,发现一个规律,就是颜色的信息与span这个标签关联。所以,我们只要找到span这个标签,传入相应的属性就行了。
import urllib.request
import urllib.parse
import urllib.error
import urllib.response
from bs4 import BeautifulSoup
request=urllib.request.Request(url="http://www.pythonscraping.com/pages/warandpeace.html")
response=urllib.request.urlopen(request)
bs=BeautifulSoup(response.read())
namelist=bs.find_all(name="span",attrs={"class":"green"})
for name in namelist:
print(name)
结果:
从原来的网页和接过来看,确实是成功了,事实上,也就加了一个参数而已。
Ⅱ.
三.正则表达式
首先正则表达式的基础以及想让你默认通过python使用正则表达式请参看,这里只是直接用正则表达式来完整爬虫功能。
正则表达式有什么用呢?下面通过一个例子来说明。
先给出一个图片网站的网页:
现代科技图片
打开之后是这个样子。
我现在想得到这个网页中所有展示的图片的链接应该怎么办呢?
很简单,首先看网站的源码
粗略的看了一下,图片文件都可以通过搜索img这个标签来找到。那么就好办了。之前例子的代码几乎可以不加改动的用到这里来,只需要改一点其中的参数的值就行。
代码:
import urllib.request
import urllib.parse
import urllib.error
import urllib.response
from bs4 import BeautifulSoup
request=urllib.request.Request(url="http://www.nipic.com/photo/xiandai/index.html")
response=urllib.request.urlopen(request)
bs=BeautifulSoup(response.read())
namelist=bs.find_all(name="img")
for name in namelist:
print(name)
得到的结果不差,想要的图片的链接都得到了。但是,最后面的几个链接是什么鬼。后面的几个链接是我并不想要的。你当然可以把所有的链接都得到,然后手动去掉。但是为什么要手动呢?
所以这个时候就要找规律了。其实你一眼看过去,正文图片的链接都是很有规律工整的,所以这里就可以直接用到正则表达式啦。
直接看结果的链接规律,我们就可以构造这样一个正则表达式:
http:\/\/img80\.nipic\.com\/file\/.+\/.+\.jpg
代码:
import urllib.request
import urllib.parse
import urllib.error
import urllib.response
from bs4 import BeautifulSoup
import re
request=urllib.request.Request(url="http://www.nipic.com/photo/xiandai/index.html")
response=urllib.request.urlopen(request)
bs=BeautifulSoup(response.read())
namelist=bs.find_all(name="img",attrs={"src":re.compile("http\:\/\/img80\.nipic\.com\/file\/.+\/.+\.jpg")})
for name in namelist:
print(name)
结果:
就成功啦。是不是很简单。