爬虫(二)

前面我们对爬虫有了一点了解,以及对数据和网络也有了一丢丢认识。当然对于爬虫还有非常多的东西,我们就不再单独进行讲解了。当我们在用到的过程中,再挑出来讲一讲。

一、编程语言

爬虫并不是一门语言的独门秘籍,Python、Java、PHP、C#、Go等语言都可以讲出精彩的故事。有人说编程语言就是宗教,不同语言的设计哲学不同,行为方式各异,“非我族类,其心必异”。Python有简洁轻松的语法,开箱即用的模块,强大快乐的社区,总可以快速构建出简单高效的解决方案。
爬虫涉及多个领域,内容包罗万象,我们会介绍一些Python的模块,比如urllib、Requests、BeautifulSoup、lxml、NLTK、Pillow等,可能还会涉及一些数据存储和分析的内容。至于如何安装Python大家百度就会找到很多教程。
至于Python的编辑器,可以使用Python自带的编辑器,也可以下载专也的Python集成开发环境,比如说PyCharm,但是这是付费软件。除此之外,开可以下载一个Anaconda3,这里面包含了非常多的Python包,不用大家再单独下载Python包,因为下载Python包是一件很复杂而且有点“玄学”的东西,Anaconda中包含了很多Python常用的包,而且也自带了Python的编辑器,比如Spyder,Jupyter Notebook等。至于如何下载,还是百度即可,非常便利。其实真正的大佬是不拘泥于编辑器的,用记事本照样能敲出非常牛逼的代码。

二、Python基础

还需要有一些Python基础需要大家注重:

  • Python数据类型。Python是弱类型语言。学好一门语言的基础就是它的数据类型。Python的数据类型有字符串、集合、列表、字典等等。
  • Python进行I/O读写操作。简单来说就是进行文件读写。
  • Python多线程以及进程间通信。我们应当知道,在网络中进行通信的实际就是连接在网络中的两台主机之间的进程在进行通信。
  • Python网络编程。比如如何用Python如何实现HTTP请求发送,以及TCP(传输控制协议)和UDP(用户数据报协议)编程等。
    下面我们来看Python是如何进行网络请求的:
    我们首先随便进入一个网页,比如说百度,然后按F12,进入浏览器的开发者模式,或者单击右键选择查看网页源代码查看。然后就可以看到网页的源代码(至于如何看网页的源代码,就是我们前面所讲的HTML以及一些CSS层叠样式表和JavaScript脚本)
    百度首页以及网页代码现在我们用Python实现来请求这个页面:
import requests  # 导入请求包
url = "https://www.baidu.com/?tn=88093251_22_hao_pg&"   # 网页的URL地址
html = requests.get(url)   # 调用requests的get函数来请求这个url
print(html)   # 输出这个请求的状态码
print(html.content)  # 输出这个网页的源代码

运行一下,现在来看这个输出的结果
请求结果
这个实例里面我们输出了两个内容:

  1. 请求状态码。这个状态码反映了我们所发出请求的结果是怎么样,比如这个我们刚刚例子中,返回的状态码是200,就说明请求成功了。不同的状态码反映了不同的请求结果,比如我们有时无法正常上网,页面上会出现404 Not Found,这个404也是一种状态码,它表示的意思就是“我们所请求的资源未找到”。除了200和404之外还有很多其他类型的状态码,感兴趣的可以点上面的链接。有了这个状态码我们,我们就可以根据状态码知道我们的请求是否成功,或者哪里出现了问题。我们还可以在刚刚进入的浏览器开发者模式查看状态码。
    浏览器查看请求状态码
    通过上图的方式,我们就可以看到这个页面的很多信息,比如上图中圈出的三个红框框:Request URL就是我们的请求地址;还有Request Method就是我们的请求方法,是GET方法,上一节已经讲过HTTP协议的请求方法;还有一个就是Status Code就是我们的状态码,上面是绿点 200 OK代表就是请求成功。这个页面中还有很多重要信息,大家应该记住上面的步骤,以便查找以后需要用到的信息。
  2. 网页源代码。网页源代码就是我们数据爬虫得到的“第一手”数据,我们需要的很多数据就在网页源代码中。
    但是我们也可以看到,我们得到的网页源代码有许多”不需要“的内容,比如HTML的各种标签,以及一些虽然在网页中但我们并不感兴趣的数据等。这些东西都是我们需要剔除掉的。那么问题就来了啊,如何把这些不要的东西给踢出去呢?这也就是对我们得到的网页源代码进行解析。常用的解析方法有很多,比如BeautifulSoup,正则,pyquery,xpath等等,下面我们先来说一下正则表达式(划重点了!!!)。
    正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。下面是正则表达式常用的一些符号
    正则表达式常用符号
    这么说正则表达式,大家估计难以理解,下面我们通过一个例子来体验一下:
import re  # 导入正则表达式所需的包
phone = "2004-959-559 # 这是一个电话号码"
# 删除注释
num = re.sub(r'#.*$', "", phone)  # 调用re包的sub函数,去除以# 开头的注释
print("电话号码 : ", num)

# 移除非数字的内容
num = re.sub(r'\D', "", phone)  # 去除非数字的内容,也就是注释,但是他也会去掉号码之间的短横线
print("电话号码 : ", num)

下面来看运行结果:
运行结果
通过正则表达式,可以把号码中的注释成功去除。当然我们也可以通过正则表达式来把我们得到的网页源代码中不需要的数据去除掉,或者只提取我们想要的内容。

三、BeautifulSoup源码解析器

BeautifulSoup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。它会将HTML页面解析生成一个BeautifulSoup对象。至于什么是对象,大家可以把它想象成一种数据结构。还是建议大家去百度一下,面向对象编程,这里就不在过多描述了。下面给出一个例子来看一个BeautifulSoup的使用:
我们先来随便准备一个HTML文档:

from bs4 import BeautifulSoup  # 导入BeautifulSoup包
# 准备一个html文档
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
</body></html>
"""
soup = BeautifulSoup(html, 'html.parser')  # 使用BeautifulSoup对html进行解析,html.parser是解析方式
print(soup.prettify())  # 将解析后的BeatuifulSoup对象按照标准的代码缩进输出

查看一下输出结果:

输出结果
然后我们可以就可以在解析出来的BeautifulSoup对象中找出我们想要的数据,比如找到所有的标签中的超链接(上节已经讲过HTML的标签)。

for link in soup.find_all('a'):  # 找出所有的<a>标签
    print(link.get('href'))   # 找出<a>标签中的href链接

我们来看下查找结果:
查找结果
这样就可以是一个非常简单的爬虫例子了,因为如我们的目的就是爬取一个网页中的跳转链接,那我们现在就已经实现了这个目的。当然这是非常简单的一个例子。
**补充说明:**刚刚我们在使用BeautifulSoup解析html代码时,使用了’html.parser’方法进行解析,还有其他方法进行解析:

解析器使用方法优势劣势
Python标准库BeautifulSoup(markup, “html.parser”)Python的内置标准库,执行速度适中,文档容错能力强Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差
lxml HTML 解析器BeautifulSoup(markup, “lxml”)速度快,文档容错能力强需要安装C语言库
lxml XML 解析器BeautifulSoup(markup, “xml”)速度快,唯一支持XML的解析器需要安装C语言库
html5libBeautifulSoup(markup, “html5lib”)最好的容错性;以浏览器的方式解析文档;生成HTML5格式的文档速度慢;不依赖外部扩展

推荐使用lxml作为解析器,因为效率更高。

四、BeautifulSoup数据对象

BeautifulSoup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种: Tag , NavigableString , BeautifulSoup , Comment。这里主要将一下Tag类型。

Tag

Tag 对象与XML或HTML原生文档中的tag相同:

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b
type(tag)
# 输出结果:<class 'bs4.element.Tag'>

Tag有很多方法和属性,现在介绍一下tag中最重要的属性: name和attributes

Name属性

每个tag都有自己的名字,通过 .name 来获取:

tag.name = "blockquote"
tag
#输出结果: <blockquote class="boldest">Extremely bold</blockquote>
Attributes属性

一个tag可能有很多个属性. tag 有一个 “class” 的属性,值为 “boldest” . tag的属性的操作方法与字典相同:

tag['class']
# u'boldest'

也可以直接”点”取属性, 比如: .attrs :

tag.attrs
# {u'class': u'boldest'}

我们可以利用 soup 加标签名轻松地获取这些标签的内容,是不是感觉比正则表达式方便多了?不过有一点是,它查找的是在所有内容中的第一个符合要求的标签,如果要查询所有的标签,我们在后面进行介绍。
对于BeautifulSoup我们有许多东西要学,小伙伴们可以在网上查找教程,或者查看BeautifulSoup的中文开发文档

五、爬虫小栗子

爬取中山大学贴标内的标题,直接上代码:

import urllib.request
from bs4 import BeautifulSoup
import time
print("\n\n\n这是一个爬虫,正在爬取百度贴吧的一个内容,请耐心等候:。。。")
# 打开我们爬取数据要保存的文件
f = open('pachong.txt', 'a+', encoding='utf-8')
# 设置日期格式,设置当地时间
end_time = time.strftime('%Y+%m+%d %H:%M:%S', time.localtime(time.time()))
# 先向文件内写入时间和标题
f.write("【时间:"+end_time+"】\n【标题】中山大学吧+\n")
# 贴吧URL地址
url = "http://tieba.baidu.com/f?ie=utf-8&kw=%E4%B8%AD%E5%B1%B1%E5%A4%A7%E5%AD%A6&fr=search&red_tag=s3174977322"
# 使用urllib包请求html页面
html = urllib.request.urlopen(url).read()
# 将请求的包使用BeautifulSoup包进行解析
soup = BeautifulSoup(html, "lxml")
# 将所有的<a>标签,并且标签使用的类为“j_th_tit"的标签内容放到all中
all = soup.find_all("a", class_="j_th_tit")
print(all)  # 打印all,查看查找<a> 标签内容的内容
ALL = str(all).split('</a>')   # 使用字符串分割函数,以</a>为分割线,将不同的<a>标签分隔开
ALL.pop()  # 依次从队列中取出一个<a>标签进行处理
i = 0
for s in ALL:
    q, w = s.split("title=")  # 找到标题内容
    i = i+1 
    f.write('【标题'+str(i)+'】'+w+"\n")   # 将标题内容写入到文件中
f.close()  # 关闭文件
print("\n\n\n恭喜你,完成任务,请你打开文件:nuc_pachong.txt查询")

查看控制台打印结果:
打印结果
从上图我们可以看到,打印字符串all的内容为网页代码中所有的类名为"j_th_tit"的a标签(至于什么是类,这就涉及到我们上节讲到的CSS的内容,大家可以在网上找一些教程来看)。这就是我们要找的每条帖子标题所在的标签,只要找到了帖子所在的标签,我们就可以从这些标签中提取出每条帖子的标题。那肯定会有人问你为什么知道每条帖子标题都存放在、<a.>标签内,且它的类class="j_th_tit"内。还记得我们之前查看网页源代码的操作吗,我们是从它的源代码分析出来的。先打开中山大学的贴吧,并进入开发者模式:
代码解析

至于为什么不单独使用a标签作为查找的标准呢,因为贴吧中有很多的a标签,并不是每条标签都是帖子的标题,所以还要加上标签的类作为查找条件,这样的查找更准确。这是一种非常简单并且有效的查找方法。
下面我们来看看爬取结果存放的文件:

爬取结果
可以看到爬去的结果还是蛮不错的。嗯今天的内容大概也就是这些了,看完这些大家是不是已经跃跃欲试了呢哈哈哈哈,小伙伴们可以按照上面的代码自己试一试,也可以在网上找一些其他的例子try一哈。对于大家尝试过程中如果有报错或者有些东西安装失败,都可以直接百度或者Google,或者在公众号后台留言,都可以个得到很好的解决,大家要学会利用网络资源啊啊。下次再见咯~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_44858167

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值