爬虫基础

爬虫框架 Scrapy
如果你是一个 Python 高手,基本的爬虫知识都已经掌握了,那么就寻觅一下 Python 框架吧,我选择的框架是
Scrapy 框架。这个框架有什么强大的功能呢?下面是它的官方介绍:
HTML, XML 源数据 选择及提取 的内置支持 提供了一系列在 spider 之间共享的可复用的过滤器(即 Item Loa
ders),对智能处理爬取数据提供了内置支持。 通过 feed 导出 提供了多格式(JSON、CSV、XML),多存储
后端(FTP、S3、本地文件系统)的内置支持 提供了 media pipeline,可以 自动下载 爬取到的数据中的图片(或
者其他资源)。 高扩展性。您可以通过使用 signals ,设计好的 API(中间件, extensions, pipelines)来定制实
现您的功能。
内置的中间件及扩展为下列功能提供了支持:
• cookies and session 处理
• HTTP 压缩
• HTTP 认证
• HTTP 缓存
• user-agent模拟
• robots.txt
爬取深度限制
针对非英语语系中不标准或者错误的编码声明, 提供了自动检测以及健壮的编码支持。
支持根据模板生成爬虫。在加速爬虫创建的同时,保持在大型项目中的代码更为一致。详细内容请参阅 genspid
er 命令。
针对多爬虫下性能评估、失败检测,提供了可扩展的 状态收集工具 。
提供 交互式 shell 终端 , 为您测试 XPath 表达式,编写和调试爬虫提供了极大的方便
提供 System service, 简化在生产环境的部署及运行
内置 Web service, 使您可以监视及控制您的机器
内置 Telnet 终端 ,通过在 Scrapy 进程中钩入 Python 终端,使您可以查看并且调试爬虫
第 1 章 综述 | 10
Logging 为您在爬取过程中捕捉错误提供了方便
支持 Sitemaps 爬取
具有缓存的 DNS 解析器
官方文档:http://doc.scrapy.org/en/latest/

等我们掌握了基础的知识,再用这个 Scrapy 框架吧!


URL 的含义
URL,即统一资源定位符,也就是我们说的网址,统一资源定位符是对可以从互联网上得到的资源的位置和访问
方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息
指出文件的位置以及浏览器应该怎么处理它。
URL 的格式由三部分组成:
1. 第一部分是协议(或称为服务方式)。
2. 第二部分是存有该资源的主机IP地址(有时也包括端口号)。
3. 第三部分是主机资源的具体地址,如目录和文件名等。

爬虫爬取数据时必须要有一个目标的URL才可以获取数据,因此,它是爬虫获取数据的基本依据,准确理解它的

含义对爬虫学习有很大帮助。


POST 和 GET 数据传送
上面的程序演示了最基本的网页抓取,不过,现在大多数网站都是动态网页,需要你动态地传递参数给它,它做
出对应的响应。所以,在访问时,我们需要传递数据给它。最常见的情况是什么?对了,就是登录注册的时候
呀。
把数据用户名和密码传送到一个 URL,然后你得到服务器处理之后的响应,这个该怎么办?下面让我来为小伙伴
们揭晓吧!
数据传送分为 POST 和 GET 两种方式,两种方式有什么区别呢?
最重要的区别是 GET 方式是直接以链接形式访问,链接中包含了所有的参数,当然如果包含了密码的话是一种
不安全的选择,不过你可以直观地看到自己提交了什么内容。POST 则不会在网址上显示所有的参数,不过如果
你想直接查看提交了什么就不太方便了,大家可以酌情选择。
POST 方式:
上面我们说了 data 参数是干嘛的?对了,它就是用在这里的,我们传送的数据就是这个参数data,下面演示一
下 POST 方式。
import urllib
import urllib2
values = {"username":"1016903103@qq.com","password":"XXXX"}
data = urllib.urlencode(values)
url = "https://passport.csdn.net/account/login?from=http://my.csdn.net/my/mycsdn"
request = urllib2.Request(url,data)
response = urllib2.urlopen(request)
print response.read()
我们引入了 urllib 库,现在我们模拟登陆 CSDN,当然上述代码可能登陆不进去,因为还要做一些设置头部 hea
der 的工作,或者还有一些参数没有设置全,还没有提及到在此就不写上去了,在此只是说明登录的原理。我们
需要定义一个字典,名字为 values,参数我设置了 username 和 password,下面利用 urllib 的 urlencode 方
法将字典编码,命名为 data,构建 request 时传入两个参数,url 和 data,运行程序,即可实现登陆,返回的便
是登陆后呈现的页面内容。当然你可以自己搭建一个 服务器来测试一下。

注意上面字典的定义方式还有一种,下面的写法是等价的


设置 Headers
有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模
拟浏览器的工作,我们需要设置一些 Headers 的属性。
首先,打开我们的浏览器,调试浏览器 F12,我用的是 Chrome,打开网络监听,示意如下,比如知乎,点登录
之后,我们会发现登陆之后界面都变化了,出现一个新的界面,实质上这个页面包含了许许多多的内容,这些内
容也不是一次性就加载完成的,实质上是执行了好多次请求,一般是首先请求HTML文件,然后加载 JS,CSS
等等,经过多次请求之后,网页的骨架和肌肉全了,整个网页的效果也就出来了。
拆分这些请求,我们只看一第一个请求,你可以看到,有个 Request URL,还有 headers,下面便是 respons
e,图片显示得不全,小伙伴们可以亲身实验一下。那么这个头中包含了许许多多是信息,有文件编码啦,压缩方
式啦,请求的 agent 啦等等。
其中,agent 就是请求的身份,如果没有写入请求身份,那么服务器不一定会响应,所以可以在 headers 中设置
agent,例如下面的例子,这个例子只是说明了怎样设置的 headers,小伙伴们看一下设置格式就好。
import urllib
import urllib2
url = 'http://www.server.com/login'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {'username' : 'cqc', 'password' : 'XXXX' }
headers = { 'User-Agent' : user_agent }
data = urllib.urlencode(values)
request = urllib2.Request(url, data, headers)
第 4 章 Urllib 库的高级用法 | 24
response = urllib2.urlopen(request)
page = response.read()
这样,我们设置了一个 headers,在构建 request 时传入,在请求时,就加入了 headers 传送,服务器若识别
了是浏览器发来的请求,就会得到响应。
另外,我们还有 对付”反盗链”的方式,对付防盗链,服务器会识别 headers 中的 referer 是不是它自己,如果
不是,有的服务器不会响应,所以我们还可以在 headers 中加入 referer
例如我们可以构建下面的headers
headers = { 'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' ,
'Referer':'http://www.zhihu.com/articles' }
同上面的方法,在传送请求时把 headers 传入 Request 参数里,这样就能应付防盗链了。
另外 headers 的一些属性,下面的需要特别注意一下:
• User-Agent : 有些服务器或 Proxy 会通过该值来判断是否是浏览器发出的请求
• Content-Type : 在使用 REST 接口时,服务器会检查该值,用来确定 HTTP Body 中的内容该怎样解析。
• application/xml : 在 XML RPC,如 RESTful/SOAP 调用时使用
• application/json : 在 JSON RPC 调用时使用
• application/x-www-form-urlencoded : 浏览器提交 Web 表单时使用
在使用服务器提供的 RESTful 或 SOAP 服务时, Content-Type 设置错误会导致服务器拒绝服务

其他的有必要的可以审查浏览器的 headers 内容,在构建时写入同样的数据即可



Proxy(代理)的设置
urllib2 默认会使用 环境变量 http_proxy 来设置 HTTP Proxy。假如一个网站它会 检测某一段时间某个IP 的访问
次数,如果访问次数过多,它会禁止你的访问。所以你可以设置一些 代理服务器来帮助你做工作,每隔一段时间
换一个代理,网站君都不知道是谁在捣鬼了,这酸爽!
下面一段代码说明了 代理的设置用法
import urllib2
enable_proxy = True
proxy_handler = urllib2.ProxyHandler({"http" : 'http://some-proxy.com:8080'})
null_proxy_handler = urllib2.ProxyHandler({})
if enable_proxy:
opener = urllib2.build_opener(proxy_handler)
else:
opener = urllib2.build_opener(null_proxy_handler)

urllib2.install_opener(opener)



Timeout 设置
上一节已经说过 urlopen 方法了,第三个参数就是 timeout 的设置,可以设置等待多久超时,为了解决一些网站
实在响应过慢而造成的影响。
例如下面的代码,如果第二个参数 data 为空那么要特别指定是 timeout 是多少,写明形参,如果data已经传
入,则不必 声明。
import urllib2
response = urllib2.urlopen('http://www.baidu.com', timeout=10)
import urllib2

response = urllib2.urlopen('http://www.baidu.com',data, 10)


使用 HTTP 的 PUT 和 DELETE 方法
http 协议有六种请求方法,get, head,put,delete,post,options,我们有时候需要用到 PUT 方式或者 DELETE
方式请求。
PUT:这个方法比较少见。HTML 表单也不支持这个。本质上来讲, PUT 和 POST 极为相似,都是向服务器
发送数据,但它们之间有一个重要区别,PUT 通常指定了资源的存放位置,而 POST 则没有,POST 的数据
存放位置由服务器自己决定。 DELETE:删除某一个资源。基本上这个也很少见,不过还是有一些地方比如a
mazon的S3云服务里面就用的这个方法来删除资源。 如果要使用 HTTP PUT 和 DELETE ,只能使用比较低
层的 httplib 库。虽然如此,我们还是能通过下面的方式,使 urllib2 能够发出 PUT 或DELETE 的请求,不过
用的次数的确是少,在这里提一下。
import urllib2
request = urllib2.Request(uri, data=data)
request.get_method = lambda: 'PUT' # or 'DELETE'

response = urllib2.urlopen(request)



使用 DebugLog
可以通过下面的方法把 Debug Log 打开,这样收发包的内容就会在屏幕上打印出来,方便调试,这个也不太常
用,仅提一下
import urllib2
httpHandler = urllib2.HTTPHandler(debuglevel=1)
httpsHandler = urllib2.HTTPSHandler(debuglevel=1)
opener = urllib2.build_opener(httpHandler, httpsHandler)
urllib2.install_opener(opener)
response = urllib2.urlopen('http://www.baidu.com')
以上便是一部分高级特性,前三个是重要内容,在后面,还有 cookies 的设置还有异常的处理,小伙伴们加油!


首先解释下 URLError 可能产生的原因:
• 网络无连接,即本机无法上网
• 连接不到特定的服务器
• 服务器不存在
在代码中,我们需要用 try-except 语句来包围并捕获相应的异常。下面是一个例子,先感受下它的风骚
import urllib2
requset = urllib2.Request('http://www.xxxxx.com')
try:
urllib2.urlopen(requset)
except urllib2.URLError, e:
print e.reason
我们利用了 urlopen 方法访问了一个不存在的网址,运行结果如下:
[Errno 11004] getaddrinfo failed
它说明了错误代号是11004,错误原因是 getaddrinfo failed
第 5 章 3 URLError | 33
# #
HTTPError
HTTPError 是 URLError 的子类,在你利用 urlopen 方法发出一个请求时,服务器上都会对应一个应答对象 re
sponse,其中它包含一个数字”状态码”。举个例子,假如 response 是一个”重定向”,需定位到别的地址
获取文档,urllib2 将对此进行处理。
其他不能处理的,urlopen 会产生一个 HTTPError,对应相应的状态吗,HTTP 状态码表示HTTP 协议所返回
的响应的状态。下面将状态码归结如下:
100:继续 客户端应当继续发送请求。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。
101: 转换协议 在发送完这个响应最后的空行后,服务器将会切换到在 Upgrade 消息头中定义的那些协议。只有在切换新的协议更有好处的时候才应该采取类似措施。
102:继续处理 由 WebDAV(RFC 2518)扩展的状态码,代表处理将被继续执行。
200:请求成功 处理方式:获得响应的内容,进行处理
201:请求完成,结果是创建了新资源。新创建资源的URI可在响应的实体中得到 处理方式:爬虫中不会遇到
202:请求被接受,但处理尚未完成 处理方式:阻塞等待
204:服务器端已经实现了请求,但是没有返回新的信 息。如果客户是用户代理,则无须为此更新自身的文档视图。 处理方式:丢弃
300:该状态码不被 HTTP/1.0 的应用程序直接使用, 只是作为 3XX 类型回应的默认解释。存在多个可用的被请求资源。 处理方式:若程序中能够处理,则进行进一步处理,如果程序中不能处理,则丢弃
301:请求到的资源都会分配一个永久的 URL,这样就可以在将来通过该 URL 来访问此资源 处理方式:重定向到分配的 URL
302:请求到的资源在一个不同的 URL 处临时保存 处理方式:重定向到临时的 URL
304:请求的资源未更新 处理方式:丢弃
400:非法请求 处理方式:丢弃
401:未授权 处理方式:丢弃
403:禁止 处理方式:丢弃
404:没有找到 处理方式:丢弃
500:服务器内部错误 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在**服务器端**的源代码出现错误时出现。
501:服务器无法识别 服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。
502:错误网关 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
503:服务出错 由于临时的**服务器**维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。
HTTPError 实例产生后会有一个 code 属性,这就是是服务器发送的相关错误号。 因为 urllib2 可以为你处理重
定向,也就是 3 开头的代号可以被处理,并且 100-299 范围的号码指示成功,所以你只能看到 400-599 的错
误号码。
下面我们写一个例子来感受一下,捕获的异常是 HTTPError,它会带有一个 code 属性,就是错误代号,另外我
们又打印了 reason 属性,这是它的父类 URLError 的属性。
import urllib2
req = urllib2.Request('http://blog.csdn.net/cqcre')
try:

urllib2.urlopen(req)


except urllib2.HTTPError, e:
print e.code
print e.reason
运行结果如下
403
Forbidden
错误代号是 403,错误原因是 Forbidden,说明服务器禁止访问。
我们知道,HTTPError 的父类是 URLError,根据编程经验,父类的异常应当写到子类异常的后面,如果子类捕
获不到,那么可以捕获父类的异常,所以上述的代码可以这么改写
import urllib2
req = urllib2.Request('http://blog.csdn.net/cqcre')
try:
urllib2.urlopen(req)
except urllib2.HTTPError, e:
print e.code
except urllib2.URLError, e:
print e.reason
else:
print "OK"
如果捕获到了 HTTPError,则输出 code,不会再处理 URLError 异常。如果发生的不是HTTPError,则会去
捕获 URLError 异常,输出错误原因。
另外还可以加入 hasattr 属性提前对属性进行判断,代码改写如下
import urllib2
req = urllib2.Request('http://blog.csdn.net/cqcre')
try:
urllib2.urlopen(req)
except urllib2.URLError, e:
if hasattr(e,"code"):
print e.code
if hasattr(e,"reason"):
print e.reason
else:
print "OK"
首先对异常的属性进行判断,以免出现属性输出报错的现象。

以上,就是对 URLError 和 HTTPError 的相关介绍,以及相应的错误处理办法,小伙伴们加油!


为什么要使用 Cookie 呢?
Cookie,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)
比如说有些网站需要登录后才能访问某个页面,在登录之前,你想抓取某个页面内容是不允许的。那么我们可以
利用 Urllib2 库保存我们登录的 Cookie,然后再抓取其他页面就达到目的了。
在此之前呢,我们必须先介绍一个 opener 的概念。
第 6 章 Cookie 的使用 | 37
# #
Opener
当你获取一个 URL 你使用一个 opener(一个 urllib2.OpenerDirector 的实例)。在前面,我们都是使用的默认的
opener,也就是 urlopen。它是一个特殊的 opener,可以理解成opener 的一个特殊实例,传入的参数仅仅是
url,data,timeout。
如果我们需要用到 Cookie,只用这个 opener 是不能达到目的的,所以我们需要创建更一般的opener 来实现对

Cookie 的设置。


Cookielib
cookielib 模块的主要作用是提供可存储 cookie 的对象,以便于与 urllib2 模块配合使用来访问 Internet 资
源。Cookielib 模块非常强大,我们可以利用本模块的 CookieJar 类的对象来捕获 cookie 并在后续连接请求时
重新发送,比如可以实现模拟登录功能。该模块主要的对象有 CookieJar、FileCookieJar、MozillaCookieJa
r、LWPCookieJar。
它们的关系:CookieJar —-派生—->FileCookieJar —-派生—–>MozillaCookieJar 和LWPCookieJar
# #
获取 Cookie 保存到变量
首先,我们先利用 CookieJar 对象实现获取 cookie 的功能,存储到变量中,先来感受一下
import urllib2
import cookielib
\#声明一个CookieJar对象实例来保存cookie
cookie = cookielib.CookieJar()
\#利用urllib2库的HTTPCookieProcessor对象来创建cookie处理器
handler=urllib2.HTTPCookieProcessor(cookie)
\#通过handler来构建opener
opener = urllib2.build_opener(handler)
\#此处的open方法同urllib2的urlopen方法,也可以传入request
response = opener.open('http://www.baidu.com')
for item in cookie:
print 'Name = '+item.name
print 'Value = '+item.value
我们使用以上方法将 cookie 保存到变量中,然后打印出了 cookie 中的值,运行结果如下
Name = BAIDUID
Value = B07B663B645729F11F659C02AAE65B4C:FG=1
Name = BAIDUPSID
Value = B07B663B645729F11F659C02AAE65B4C
Name = H\_PS\_PSSID
Value = 12527\_11076\_1438\_10633
Name = BDSVRTM

Value = 0


保存 Cookie 到文件
在上面的方法中,我们将 cookie 保存到了 cookie 这个变量中,如果我们想将 cookie 保存到文件中该怎么做
呢?这时,我们就要用到
FileCookieJar 这个对象了,在这里我们使用它的子类 MozillaCookieJar 来实现 Cookie的保存
import cookielib
import urllib2
\#设置保存cookie的文件,同级目录下的cookie.txt
filename = 'cookie.txt'
\#声明一个MozillaCookieJar对象实例来保存cookie,之后写入文件
cookie = cookielib.MozillaCookieJar(filename)
\#利用urllib2库的HTTPCookieProcessor对象来创建cookie处理器
handler = urllib2.HTTPCookieProcessor(cookie)
\#通过handler来构建opener
opener = urllib2.build_opener(handler)
\#创建一个请求,原理同urllib2的urlopen
response = opener.open("http://www.baidu.com")
\#保存cookie到文件
cookie.save(ignore_discard=True, ignore_expires=True)
关于最后 save 方法的两个参数在此说明一下:
官方解释如下:
ignore_discard: save even cookies set to be discarded. ignore_expires: save even cookies that hav
e expiredThe file is overwritten if it already exists
由此可见,ignore_discard 的意思是即使 cookies 将被丢弃也将它保存下来,ignore_expires 的意思是如果在
该文件中 cookies 已经存在,则覆盖原文件写入,在这里,我们将这两个全部设置为 True。运行之后,cookies

将被保存到 cookie.txt文件中,我们查看一下内容,附图如下



从文件中获取 Cookie 并访问
那么我们已经做到把 Cookie 保存到文件中了,如果以后想使用,可以利用下面的方法来读取cookie 并访问网
站,感受一下
import cookielib
import urllib2
\#创建MozillaCookieJar实例对象
cookie = cookielib.MozillaCookieJar()
\#从文件中读取cookie内容到变量
cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True)
\#创建请求的request
req = urllib2.Request("http://www.baidu.com")
\#利用urllib2的build_opener方法创建一个opener
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
response = opener.open(req)
print response.read()
设想,如果我们的 cookie.txt 文件中保存的是某个人登录百度的 cookie,那么我们提取出这个 cookie 文件内
容,就可以用以上方法模拟这个人的账号登录百度。
# #
利用 cookie 模拟网站登录
下面我们以我们学校的教育系统为例,利用 cookie 实现模拟登录,并将 cookie 信息保存到文本文件中,来感受
一下 cookie 大法吧!
第 6 章 Cookie 的使用 | 41
import urllib
import urllib2
import cookielib
filename = 'cookie.txt'
\#声明一个MozillaCookieJar对象实例来保存cookie,之后写入文件
cookie = cookielib.MozillaCookieJar(filename)
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
postdata = urllib.urlencode({
'stuid':'201200131012',
'pwd':'23342321'
})
\#登录教务系统的URL
loginUrl = 'http://jwxt.sdu.edu.cn:7890/pls/wwwbks/bks\_login2.login'
\#模拟登录,并把cookie保存到变量
result = opener.open(loginUrl,postdata)
\#保存cookie到cookie.txt中
cookie.save(ignore\_discard=True, ignore\_expires=True)
\#利用cookie请求访问另一个网址,此网址是成绩查询网址
gradeUrl = 'http://jwxt.sdu.edu.cn:7890/pls/wwwbks/bkscjcx.curscopre'
\#请求访问成绩查询网址
result = opener.open(gradeUrl)
print result.read()
以上程序的原理如下
创建一个带有 cookie 的 opener,在访问登录的 URL 时,将登录后的 cookie 保存下来,然后利用这个 cookie
来访问其他网址。

如登录之后才能查看的 成绩查询呀,本学期课表呀等等网址,模拟登录就这么实现啦,是不是很酷炫?



Beautiful Soup 的简介
简单来说,Beautiful Soup 是 python 的一个库,最主要的功能是从网页抓取数据。官方解释如下:
Beautiful Soup 提供一些简单的、python 式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具
箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程
序。
Beautiful Soup 自动将输入文档转换为 Unicode 编码,输出文档转换为 utf-8 编码。你不需要考虑编码方
式,除非文档没有指定一个编码方式,这时,Beautiful Soup 就不能自动识别编码方式了。然后,你仅仅需要
说明一下原始编码方式就可以了。
Beautiful Soup 已成为和 lxml、html6lib 一样出色的 python 解释器,为用户灵活地提供不同的解析策略或强

劲的速度


Beautiful Soup 安装
Beautiful Soup 3 目前已经停止开发,推荐在现在的项目中使用 Beautiful Soup 4,不过它已经被移植到 BS4
了,也就是说导入时我们需要 import bs4 。所以这里我们用的版本是 Beautiful Soup 4.3.2 (简称BS4),另外
据说 BS4 对 Python3 的支持不够好,不过我用的是 Python2.7.7,如果有小伙伴用的是 Python3 版本,可以
考虑下载 BS3 版本。
如果你用的是新版的 Debain 或 Ubuntu,那么可以通过系统的软件包管理来安装,不过它不是最新版本,目前是
4.2.1版本
sudo apt-get install Python-bs4
如果想安装最新的版本,请直接下载安装包来手动安装,也是十分方便的方法。在这里我安装的是 Beautiful So
up 4.3.2
Beautiful Soup 3.2.1
Beautiful Soup 4.3.2
下载完成之后解压
运行下面的命令即可完成安装
sudo python setup.py install

如下图所示,证明安装成功了


创建 Beautiful Soup 对象
首先必须要导入 bs4 库
from bs4 import BeautifulSoup
我们创建一个字符串,后面的例子我们便会用它来演示
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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>
"""
创建 beautifulsoup 对象
soup = BeautifulSoup(html)
另外,我们还可以用本地 HTML 文件来创建对象,例如
soup = BeautifulSoup(open('index.html'))
上面这句代码便是将本地 index.html 文件打开,用它来创建 soup 对象
下面我们来打印一下 soup 对象的内容,格式化输出
print soup.prettify()
<html>
<head>
<title>
The Dormouse's story
</title>
以上便是输出结果,格式化打印出了它的内容,这个 函数经常用到,小伙伴们要记好咯。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值