• Python 爬虫从入门到进阶之路(二)


    上一篇文章我们对爬虫有了一个初步认识,本篇文章我们开始学习 Python 爬虫实例。

    在 Python 中有很多库可以用来抓取网页,其中内置了 urllib 模块,该模块就能实现我们基本的网页爬取。

    在 Python2.x 和 Python3.x 中 urllib 模块是不一样的,但是用法上差不多,我们先用 Python2.x 中的 urllib 来实现一个 demo。

    在 Python2.x 中内置了 urllib 模块,但是 Python 创始人 Guido van Rossum 觉得其太臃肿了,于是又写了一个 urllib2,两者有很多不同,最显著的如下:

    (1)urllib仅可以接受URL,不能创建,设置headers的request类实例;

    (2)但是urllib提供urlencode()方法用来GET查询字符串的产生,而urllib2则没有(这是urllib和urllib2经常一起使用的主要原因)

    (3)编码工作使用urllib的urlencode()函数,帮我们讲key:value这样的键值对转换成‘key=value’这样的字符串,解码工作可以使用urllib的unquote()

    函数

    我们就使用 urllib2 来实现一个简单的爬虫:

    1 # 导入urllib2 库
    2 import urllib2
    3 
    4 # 向指定的url发送请求,并返回服务器响应的类文件对象
    5 response = urllib2.urlopen("http://www.baidu.com")
    6 # 类文件对象支持 文件对象的操作方法,如read()方法读取文件全部内容,返回字符串
    7 html = response.read().decode("utf-8")
    8 # 打印字符串
    9 print(html)

    在上面的代码中我们其实就相当于模拟了查看百度首页,然后获取百度首页的 html 内容。

    urllib2 在 python3.x 中被改为urllib.request,python2.x 的 urllib 和 urllib2 在 python3.x 中合并为 urllib

    在 Python3.x 中实现上面的代码如下:

    1 # 导入urllib 库
    2 import urllib.request
    3 
    4 # 向指定的url发送请求,并返回服务器响应的类文件对象
    5 response = urllib.request.urlopen("http://www.baidu.com")
    6 # 类文件对象支持 文件对象的操作方法,如read()方法读取文件全部内容,返回字符串
    7 html = response.read().decode("utf-8")
    8 # 打印字符串
    9 print(html)

    最终的打印结果如下,内容太长就截一小段:

    历史的车轮滚滚而来,虽然大部分 Python 使用者还在使用 Python2.x,但 Python3.x 肯定有其之长才被发布的,本人作为小白,就选取 Python3.x 学习吧。

    在我们上面的例子中,urlopen()的参数就是一个url地址;

    但是如果需要执行更复杂的操作,比如增加HTTP报头,必须创建一个 Request 实例来作为urlopen()的参数;而需要访问的url地址则作为 Request 实例的参数。

     1 # 导入urllib 库
     2 import urllib.request
     3 
     4 # url 作为Request()方法的参数,构造并返回一个Request对象
     5 request = urllib.request.Request("http://www.baidu.com")
     6 # Request对象作为urlopen()方法的参数,发送给服务器并接收响应
     7 response = urllib.request.urlopen(request)
     8 # 类文件对象支持 文件对象的操作方法,如read()方法读取文件全部内容,返回字符串
     9 html = response.read().decode("utf-8")
    10 # 打印字符串
    11 print(html)

    最终的打印结果一致。

    新建Request实例,除了必须要有 url 参数之外,还可以设置另外两个参数:

    1. data(默认空):是伴随 url 提交的数据(比如要post的数据),同时 HTTP 请求将从 "GET"方式 改为 "POST"方式。

    2. headers(默认空):是一个字典,包含了需要发送的HTTP报头的键值对。

    这两个参数下面会说到。

    但是这样直接用 urllib 给一个网站发送请求的话,确实略有些唐突了,就好比,人家每家都有门,你以一个路人的身份直接闯进去显然不是很礼貌。而且有一些站点不喜欢被程序(非人为访问)访问,有可能会拒绝你的访问请求。

    但是如果我们用一个合法的身份去请求别人网站,显然人家就是欢迎的,所以我们就应该给我们的这个代码加上一个身份,就是所谓的User-Agent头。

    • 浏览器 就是互联网世界上公认被允许的身份,如果我们希望我们的爬虫程序更像一个真实用户,那我们第一步,就是需要伪装成一个被公认的浏览器。用不同的浏览器在发送请求的时候,会有不同的User-Agent头。

    现在我们就来加一个 User-Agent 的报头。

    当我们打开 https://www.baidu.com/,我们在开发者工具的 Network 下,我们会找到一个 

    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36

    当然还有 Accept,Host,Cookie 等信息,这里我们先不考虑,后期会讲到。

     1 # 导入urllib 库
     2 import urllib.request
     3 import ssl
     4 
     5 # 取消代理验证
     6 ssl._create_default_https_context = ssl._create_unverified_context
     7 # User-Agent
     8 headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"}
     9 # url 作为Request()方法的参数,构造并返回一个Request对象
    10 request = urllib.request.Request("http://www.baidu.com",headers=headers)
    11 # Request对象作为urlopen()方法的参数,发送给服务器并接收响应
    12 response = urllib.request.urlopen(request)
    13 # 类文件对象支持 文件对象的操作方法,如read()方法读取文件全部内容,返回字符串
    14 html = response.read().decode("utf-8")
    15 # 打印字符串
    16 print(html)

    在上面的代码中,我们又引入了 ssl 模块,由于现在百度使用的是 https 协议,进入页面需要代理验证,为了不必要的麻烦,我们干脆取消代理验证,所以用到了 ssl 模块。

    然后我们定义了一个 headers 的变量,即响应头信息,然后我们在 Request 的第二个形参中将 headers=headers,这样我们在请求 https://www.baidu.com/,就相当于我们手动在浏览器输入 url 链接是一样的效果。

  • 相关阅读:
    C#深入浅出 修饰符(二)
    HDU 5785 Interesting
    HDU 5783 Divide the Sequence
    HDU 5781 ATM Mechine
    UVA 714 Copying Books
    uva 1471 Defense Lines
    UVA 11134 Fabled Rooks
    UVA 11572 Unique Snowflakes
    UVA 11093 Just Finish it up
    UVA 10954 Add All
  • 原文地址:https://www.cnblogs.com/weijiutao/p/10735533.html
Copyright © 2020-2023  润新知