背景
由于毕业论文的需要,开始学习爬虫相关知识,本博客会记录本人从刚刚接触爬虫到完成毕业论文之中使用爬虫的相关知识。
简单爬虫代码
from urllib.request import urlopen
urllib是py的库,从这个库中调用request模块导入urlopen函数。urllib库包含了从网页请求数据,处理cookie等内容。
urlopen用来打开并读取一个从网络获取的远程对象,它可以轻松的读取HTML文件,图像文件或者其他文件流。
首先先要安装BeautifulSoup第三方库,这里就不手把手说明了
from urllib.request import urlopen
from bs4 import BeautifulSoup
from requests import HTTPError
def getTitle(url):
try:
html = urlopen(url)
except HTTPError as e:
return None
try:
bs = BeautifulSoup(html.read(),'html.parser')
title = bs.body.h1
except AttributeError as e:
return None
return title
title = getTitle('https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_9825826206158153022%22%7D&n_type=0&p_from=1')
if title == None:
print('Title could not be found')
else:print(title)
主函数传入网址到getTitle()函数中,然后处理了两个异常。
1.网页在服务器上不存在
发生此异常时,程序会返回HTTP错误,也就是404,500之类的错误。urlopen函数在遇到这类问题后都会抛出HTTPError。
2.服务器不存在
链接打不开,或者时URL链接写错了,就会出现URLError。这是由于对面服务器负责传回HTTP状态码,但是对面服务器出现问题时HTTP状态码就无法返回,不能抛出HTTPError。
再来看BeautifulSoup函数,第一个参数html.read()
是该对象所基于的HTML文本,第二个参数是解析器。这里用的是html.parser
还有两个常用的lxml
和html5lib
解析器。这两个是需要自己去安装的,好处是这两者对HTML代码容错性比较高,如(标签未闭合,嵌套错误,缺失标签)都能很好的识别。
此时的bs
这个参数就是HTML代码了,然后根据我们想要提取的内容(此处是提取的body标签中的h1标签),bs.head(提取头标签)。若是返回None,则该HTML中没有你想提取的标签内容。
CSS获取
当网站存在CSS代码时对于爬虫来说是最合适的了,因为我们可以根据class属性的值区分出标签,从而获取相应的信息。
下面说明两个函数:
1.find find(tag,attributes,recursive,text,keywords)
2.find_all find_all(tag,attributes,recursive,text,limit,keywords)
tag为标签列表,find_all([h1,title,div])这样传入标签列表,爬取列表内标签内容。
attributes是用python字典封装一个标签的属性,findall(‘span’,{’class‘:{‘green’}})提取span标签中绿色的文本。
recursive,默认是True。设置为False时只会爬取一级标签,True可以爬取子标签
limit只在find_all中,设置此值可以爬取前x个内容,顺序是网站默认的顺序。
例子:点击
在上面网站中我们想要提取绿色的人名。
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen('http://www.pythonscraping.com/pages/warandpeace.html')
bs = BeautifulSoup(html.read(),'html.parser')
nameList = bs.find_all('span',{'class':'green'})
for i in nameList:
print(i.get_text())
bs.find_all返回一个标签列表,每个元素都是带标签的,使用get_text()会把超链接,段落,标签去除,留下文本内容。
没有使用get_text()
使用了get_text()
导航树
导航树就是HTML代码的层次分级,父标签与子标签通过导航树能够很快的确定关系
HTML
-body
--div.wrapper
---h1
---div.content
---table
----tr
-----th
-----th
-----th
一个粗略的导航树结构
子标签和后代标签
子标签就是父标签的下一级,后代标签是指父标签下面的所有标签,一般情况下,BeautifulSoup总是处理当前标签的后代标签。如:bs.body.h1选择了body标签后代里的第一个h1标签,不回去查找body外的标签。
假设上述网站
这个是表格的HTML结构,假设我要输出整张表。
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen('http://www.pythonscraping.com/pages/page3.html')
bs = BeautifulSoup(html.read(),'html.parser')
nameList = bs.find('table',{'id':'giftList'}).children
for i in nameList:
print(i)
print(1)
输出:
我们发现,表头和表中的内容都被输出了,包括img标签中的内容。我还用1做了一下分割,打印的结构是以《tr》标签分割的。因为《table》标签中的子标签就是《tr》。
假设我不想要表头,只想输出表的数据应该怎么办呢。 这里介绍一下next_siblings。
兄弟标签,就是和选中的标签同级的标签都叫兄弟标签(和树的兄弟节点一个意思)。我们可以选中第一个《tr》标签,然后再输出他的兄弟,就能满足我们的目的。
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen('http://www.pythonscraping.com/pages/page3.html')
bs = BeautifulSoup(html.read(),'html.parser')
nameList = bs.find('table',{'id':'giftList'}).tr.next_siblings
for i in nameList:
print(i)
print(1)
出了第一行的表头,剩下的标签都被输出了。那么假设现在我们不需要标签,只要表格的内容应该怎么办。
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen('http://www.pythonscraping.com/pages/page3.html')
bs = BeautifulSoup(html.read(),'html.parser')
nameList = bs.table.find_all('td')
for i in nameList:
print(i.get_text())
print(1)
查找出所有的《td》,然后用get_text()去掉标签,就可以获得表格内容。(因为这里只有一张table,直接.table了)