python网络数据采集学习笔记(一)

目前python已成为主流编程语言之一,在我们这个年纪多学一点知识总是好的,感觉自己经常碌碌无为平庸而过,研究生生活虽然不精彩,但是自己不能放弃自己。以后我会每天自己学一些新的内容,然后发学习笔记作为勉励自己的见证,欢迎大家一起努力。
python之前学过一点基础,看的是《Python编程:从入门到实践》,百度云链接:https://pan.baidu.com/s/1CL7qy7fSmcjaUQfz3DhDjQ 提取码: nkkk
现在学习关于python的爬虫,学习书目为《python网络数据采集》,百度云链接:https://pan.baidu.com/s/1SMxVqjM7aU7BBmGIn3CYtQ 提取码: ekuj

1、网络连接

先来看下面代码1

from urllib.request import urlopen
        html = urlopen("http://pythonscraping.com/pages/page1.html")
        print(html.read())

输出结果为:

b'\n\nA Useful Page\n\n\n

An Interesting Title

\n
\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n
\n\n\n'

分析:
这段代码输出 http://pythonscraping.com/pages/page1.html 这个网页的全部 HTML 代码。更准确地说,这会输出在域名为 http://pythonscraping.com 的服务器上 < 网络应用根地址 >/pages 文件夹里的 HTML 文件 page1.html 的源代码。

from urllib.request import urlopen:查找 Python 的 request 模块(在 urllib 库里面),只导入一个urlopen 函数。urllib是 Python 的标准库,包含了从网络请求数据,处理 cookie,甚至改变像请求头和用户代理这些元数据的函数。官方文档链接:https://docs.python.org/3/library/urllib.html。
这是python3里的,而python2中模块为urllib2。

urlopen 用来打开并读取一个从网络获取的远程对象。因为它是一个非常通用的库(它可以轻松读取 HTML 文件、图像文件,或其他任何文件流)。

2、BeautifulSoup简介

BeautifulSoup通过定位 HTML 标签来格式化和组织复杂的网络信息,用简单易用的 Python 对象为我们展现 XML 结构信息。BeautifulSoup 库不是 Python 标准库,因此需要单独安装,我用的是pycharm, 因此可以在环境设置里直接用pip安装。

代码2

 from urllib.request import urlopen
 from bs4 import BeautifulSoup
 html = urlopen("http://www.pythonscraping.com/pages/page1.html")
 bsObj = BeautifulSoup(html.read())
 print(bsObj.h1)

和代码1一样,我们导入 urlopen,然后调用 html.read() 获取网页的 HTML 内容。这样就可以把 HTML 内容传到 BeautifulSoup 对象,转换成下面的结构:

html → ......
— head → A Useful Page<title></head>
  — title → <title>A Useful Page
 — body → 

An Int...

Lorem ip...
— h1 →

An Interesting Title

— div →
Lorem Ipsum dolor...

我们从网页中提取的h1 标签被嵌在 BeautifulSoup 对象 bsObj 结构的第二层
(html → body → h1)。但是,当我们从对象里提取 h1 标签的时候,可以直接调用它:bsObj.h1,也可以用bsObj.html.body.h1,bsObj.body.h1,bsObj.html.h1。

但是我在运行上述代码2的时候报错了,报错原因:
UserWarning: No parser was explicitly specified, so I’m using the best available HTML parser for this system (“html.parser”). This usually isn’t a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.
它的意思就是如果这个代码运行在其他系统或不同的虚拟环境里,会使用不同的剖析器(parser)和显示不同的结果,即没有定义parser,按照它的意见,适用这个系统的最好的parser为html.parser,因此只要将第四行代码改为:

bsObj = BeautifulSoup(html.read(),"html.parser")

便能完美解决。运行结果为:

An Interesting Title

3、可靠的网络连接

html = urlopen("http://www.pythonscraping.com/pages/page1.html")

在运行这一句代码时,会发生两种异常:
• 网页在服务器上不存在(或者获取页面的时候出现错误)
• 服务器不存在
第一种异常发生时,程序会返回 HTTP 错误。HTTP 错误可能是“404 Page Not Found”“500 Internal Server Error”等。所有类似情形,urlopen 函数都会抛出“HTTPError”异常。可以用下面的方式处理这种异常:

try:
     html = urlopen("http://www.pythonscraping.com/pages/page1.html")
except HTTPError as e:
     print(e)
     # 返回空值,中断程序,或者执行另一个方案
else:
     # 程序继续。注意:如果你已经在上面异常捕捉那一段代码里返回或中断(break),
     # 那么就不需要使用else语句了,这段代码也不会执行

如果程序返回 HTTP 错误代码,程序就会显示错误内容,不再执行 else 语句后面的代码。如果服务器不存在(就是说链接 http://www.pythonscraping.com/ 打不开,或者是 URL 链接写错了),urlopen 会返回一个 None 对象。这个对象与其他编程语言中的 null 类似。我们可以增加一个判断语句检测返回的 html 是不是 None:

if html is None:
    print("URL is not found")
else:
    # 程序继续

即使网页已经从服务器成功获取,如果网页上的内容并非完全是我们期望的那样,仍然可能会出现异常。每当你调用 BeautifulSoup 对象里的一个标签时,增加一个检查条件保证标签确实存在是很聪明的做法。如果你想要调用的标签不存在,BeautifulSoup 就会返回 None 对象。不过,如果再调用这个 None 对象下面的子标签,就会发生 AttributeError错误。

print(bsObj.nonExistentTag)

nonExistentTag 是虚拟的标签,BeautifulSoup 对象里实际没有,因此上条代码会返回一个 None 对象。处理和检查这个对象是十分必要的。如果你不检查,直接调用这个None 对象的子标签,麻烦就来了:

print(bsObj.nonExistentTag.someTag)

这条代码会返回一个错误:

AttributeError: 'NoneType' object has no attribute 'someTag'

因此,最后综合的代码3如下:

from urllib.request import urlopen
from urllib.error import HTTPError
from bs4 import BeautifulSoup
def getTitle(url):
    try:
        html = urlopen(url)
    except HTTPError as e:
        return None
    try:
        bsObj = BeautifulSoup(html.read(),"html.parser")
        title = bsObj.body.h1
    except AttributeError as e:
        return None
    return title
title = getTitle("http://www.pythonscraping.com/pages/page1.html")
if title == None:
    print("Title could not be found")
else:
    print(title)

你可能感兴趣的:(python网络数据采集学习笔记(一))