zoukankan      html  css  js  c++  java
  • Python爬虫模块使用方法

    Python爬虫模块使用

    requests模块

    Requests模块是在Python内置模块的基础上进行了高度的封装,主要用来发送HTTP网络请求,可以轻而易举的完成浏览器的任何操作。 Requests模块比urllib2模块更简洁。

    使用步骤

    1. 可以直接使用python pip进行安装

       >>>pip install requests
      
    2. 导入模块

      import requests
      
    3. 定制请求头headers

      headers = {
          'Host': 'node16.sleap.com:8089',
          'Referer': 'http://node16.sleap.com:8089/leapid-admin/view/login.html?cb=http%3A%2F%2Fnode15.sleap.com%3A2017',
          'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
      }
      r = requests.get(url, headers=headers)
      
    4. 发送请求

      #######r为Response对象,我们可以从这个对象中获取请求返回的信息。###########
      r = requests.get('https://api.github.com/events')
      r = requests.post('http://httpbin.org/post', data = {'key':'value'})
      r = requests.put('http://httpbin.org/put', data = {'key':'value'})
      r = requests.delete('http://httpbin.org/delete')
      r = requests.head('http://httpbin.org/get')
      r = requests.options('http://httpbin.org/get')
      
    5. 传递URL参数

      httpbin.org/get?key=val。

      #####Requests 允许你使用 params 关键字参数,以一个字符串字典来提供这些参数#####
      payload = {'key1': 'value1', 'key2': 'value2'}
      r = requests.get("http://httpbin.org/get", params=payload)
      

      通过打印输出该 URL,你能看到 URL 已被正确编码:

      >>> print(r.url)
      http://httpbin.org/get?key1=value1&key2=value2&key2=value3
      
    6. 响应内容

      Requests 会自动解码来自服务器的内容。大多数 unicode 字符集都能被无缝地解码。

      >>> r = requests.get('https://api.github.com/events')
      >>> r.text
      u'[{"repository":{"open_issues":0,"url":"https://github.com/...
      

      你可以找出 Requests 使用了什么编码,并且能够使用 r.encoding 属性来改变它:

      >>> r.encoding
      'utf-8'
      >>> r.encoding = 'ISO-8859-1'
      
    7. JSON响应内容

      Requests 中也有一个内置的 JSON 解码器,助你处理 JSON 数据:

      >>> r = requests.get('https://api.github.com/events')
      >>> r.json()
      [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
      

      如果 JSON 解码失败, r.json() 就会抛出一个异常。例如,响应内容是 401 (Unauthorized),尝试访问 r.json() 将会抛出 ValueError: No JSON object could be decoded 异常。

    8. 复杂的POST请求

      发送一些编码为表单形式的数据——非常像一个 HTML 表单。要实现这个,只需简单地传递一个字典给 data 参数。你的数据字典在发出请求时会自动编码为表单形式:

      >>> payload = {'key1': 'value1', 'key2': 'value2'}
      >>> r = requests.post("http://httpbin.org/post", data=payload)
      >>> print(r.text)
      {
        ...
        "form": {
          "key2": "value2",
          "key1": "value1"
        },
        ...
      }
      
    9. 响应状态码

      我们可以通过r.status_code检测响应状态码:

      >>> r = requests.get('http://httpbin.org/get')
      >>> r.status_code
      200
      
    10. 响应头

      >>> r.headers
      
    11. Cookie

      如果某个响应中包含一些 cookie,你可以快速访问它们:

      >>> url = 'http://example.com/some/cookie/setting/url'
      >>> r = requests.get(url)
      >>> r.cookies['example_cookie_name']
      'example_cookie_value'
      

      发送得到的cookie到服务器,可以使用cookie参数:

      >>> url = 'http://httpbin.org/cookies'
      >>> cookies = dict(cookies_are='working')
      >>> r = requests.get(url, cookies=cookies)
      >>> r.text
      '{"cookies": {"cookies_are": "working"}}'
      

      Cookie 的返回对象为 RequestsCookieJar,它的行为和字典类似,但接口更为完整,适合跨域名跨路径使用。你还可以把 Cookie Jar 传到 Requests 中:

      >>> jar = requests.cookies.RequestsCookieJar()
      >>> jar.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies')
      >>> jar.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere')
      >>> url = 'http://httpbin.org/cookies'
      >>> r = requests.get(url, cookies=jar)
      >>> r.text
      '{"cookies": {"tasty_cookie": "yum"}}'
      
    12. 会话对象

      会话对象让你能够跨请求保持某些参数。它也会在同一个 Session 实例发出的所有请求之间保持 cookie,所以如果你向同一主机发送多个请求,底层的 TCP 连接将会被重用,从而带来显著的性能提升。
      会话对象具有主要的 Requests API 的所有方法。
      跨请求保持一些 cookie:

      s = requests.Session()
      
      s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
      r = s.get("http://httpbin.org/cookies")
      
      print(r.text)
      # '{"cookies": {"sessioncookie": "123456789"}}'
      
    13. 请求与响应对象

      任何时候进行了类似requests.get()的调用,你都在做两件主要的事情。其一,你在构建一个Request对象, 该对象将被发送到某个服务器请求或查询一些资源。 其二,一旦requests得到一个从服务器返回的响应就会产生一个Response对象。该响应对象包含服务器返回的所有信息,也包含你原来创建的Request对象。
      如果想访问服务器返回给我们的响应头部信息,可以这样做:

      >>> r.headers
      

      如果想得到发送到服务器的请求的头部,我们可以简单地访问该请求,然后是该请求的头部:

      >>> r.request.headers
      

    urllib模块

    urllib 库用于操作网页 URL,并对网页的内容进行抓取处理。

    urllib 包 包含以下几个模块:

    • urllib.request - 打开和读取 URL。
    • urllib.error - 包含 urllib.request 抛出的异常。
    • urllib.parse - 解析 URL。
    • urllib.robotparser - 解析 robots.txt 文件。

    使用步骤

    1. 打开一个 URL

      urlopen ,然后使用 read() 函数获取网页的 HTML 实体代码。

      urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None,capath=None, cadefault=False, context=None)
      # url:url 地址。
      # data:发送到服务器的其他数据对象,默认为 None。
      # timeout:设置访问超时时间。
      # cafile 和 capath:cafile 为 CA 证书, capath 为 CA 证书的路径,使用 HTTPS 需要用到。
      # cadefault:已经被弃用。
      # context:ssl.SSLContext类型,用来指定 SSL 设置。
      # read() 是读取整个网页内容,我们可以指定读取的长度。
      
    2. 读取网页内容

      除了 read() 函数外,还包含以下两个读取网页内容的函数:

      #readline() - 读取文件的一行内容
      from urllib.request import urlopen
      myURL = urlopen("https://www.runoob.com/")
      print(myURL.readline()) #读取一行内容
      
      #readlines() - 读取文件的全部内容,它会把读取的内容赋值给一个列表变量。
      from urllib.request import urlopen
      myURL = urlopen("https://www.runoob.com/")
      lines = myURL.readlines()
      for line in lines:
          print(line) 
      
    3. 判断网页正常访问

      #我们在对网页进行抓取时,经常需要判断网页是否可以正常访问,这里我们就可以使用 getcode() 函数获取网页状态码,返回 200 说明网页正常,返回 404 说明网页不存在:
      import urllib.request
      
      myURL1 = urllib.request.urlopen("https://www.runoob.com/")
      print(myURL1.getcode())   # 200
      
      try:
          myURL2 = urllib.request.urlopen("https://www.runoob.com/no.html")
      except urllib.error.HTTPError as e:
          if e.code == 404:
              print(404)   # 404
      
    4. 抓取的网页保持到本地

      #如果要将抓取的网页保持到本地,可以使用 Python3 File write() 方法
      from urllib.request import urlopen
      
      myURL = urlopen("https://www.runoob.com/")
      f = open("runoob_urllib_test.html", "wb")
      content = myURL.read()  # 读取网页内容
      f.write(content)
      f.close()
      #执行以上代码,在本地就会生成一个 runoob_urllib_test.html 文件,里面包含了网页的内容
      
    5. URL 的编码与解码

      #编码与解码可以使用 urllib.request.quote() 与 urllib.request.unquote()方法
      import urllib.request
      
      encode_url = urllib.request.quote("https://www.runoob.com/")  # 编码
      print(encode_url)
      
      unencode_url = urllib.request.unquote(encode_url)    # 解码
      print(unencode_url)
      
      #out
      https%3A//www.runoob.com/
      https://www.runoob.com/
      
    6. 模拟头部信息

      #我们抓取网页一般需要对 headers(网页头信息)进行模拟,这时候需要使用到urllib.request.Request 类
      
      class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
      
      #url:url 地址。
      #data:发送到服务器的其他数据对象,默认为 None。
      #headers:HTTP 请求的头部信息,字典格式。
      #origin_req_host:请求的主机地址,IP 或域名。
      #unverifiable:很少用整个参数,用于设置网页是否需要验证,默认是False。。
      #method:请求方法, 如 GET、POST、DELETE、PUT等。
      
    7. 异常

      urllib.error 模块为 urllib.request 所引发的异常定义了异常类,基础异常类是 URLError。

      urllib.error 包含了两个方法,URLError 和 HTTPError。

      URLError 是 OSError 的一个子类,用于处理程序在遇到问题时会引发此异常(或其派生的异常),包含的属性 reason 为引发异常的原因。

      HTTPError 是 URLError 的一个子类,用于处理特殊 HTTP 错误例如作为认证请求的时候,包含的属性 code 为 HTTP 的状态码, reason 为引发异常的原因,headers 为导致 HTTPError 的特定 HTTP 请求的 HTTP 响应头。

      #对不存在的网页抓取并处理异常
      import urllib.request
      import urllib.error
      
      myURL1 = urllib.request.urlopen("https://www.runoob.com/")
      print(myURL1.getcode())   # 200
      
      try:
          myURL2 = urllib.request.urlopen("https://www.runoob.com/no.html")
      except urllib.error.HTTPError as e:
          if e.code == 404:
              print(404)   # 404
      
    8. 解析

      urllib.parse 用于解析 URL

      urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
      #urlstring 为 字符串的 url 地址,scheme 为协议类型
      #allow_fragments 参数为 false,则无法识别片段标识符。相反,它们被解析为路径,参数或查询组件的一部分,并 fragment 在返回值中设置为空字符串。
      
      from urllib.parse import urlparse
      
      o = urlparse("https://www.runoob.com/?s=python+%E6%95%99%E7%A8%8B")
      print(o)
      
      #out
      ParseResult(scheme='https', netloc='www.runoob.com', path='/', params='', query='s=python+%E6%95%99%E7%A8%8B', fragment='')
      #从结果可以看出,内容是一个元组,包含 6 个字符串:协议,位置,路径,参数,查询,判断
      
      #还可以直接读取协议内容
      from urllib.parse import urlparse
      
      o = urlparse("https://www.runoob.com/?s=python+%E6%95%99%E7%A8%8B")
      print(o.scheme)
      
      #out
      https
      

      urllib.robotparser 用于解析 robots.txt 文件。

      robots.txt(统一小写)是一种存放于网站根目录下的 robots 协议,它通常用于告诉搜索引擎对网站的抓取规则。

      urllib.robotparser 提供了 RobotFileParser 类,这个类提供了一些可以读取、解析 robots.txt 文件的方法。

      class urllib.robotparser.RobotFileParser(url='')
      
      #set_url(url) 设置 robots.txt 文件的 URL。
      
      #read() 读取 robots.txt URL 并将其输入解析器。
      
      #parse(lines) 解析行参数。
      
      #can_fetch(useragent, url) 如果允许 useragent 按照被解析 robots.txt 文件中的规则来获取 url 则返回 True。
      
      #mtime() 返回最近一次获取 robots.txt 文件的时间。 这适用于需要定期检查 robots.txt 文件更新情况的长时间运行的网页爬虫。
      
      #modified() 将最近一次获取 robots.txt 文件的时间设置为当前时间。
      
      #crawl_delay(useragent) 为指定的 useragent 从 robots.txt 返回 Crawl-delay 形参。 如果此形参不存在或不适用于指定的 useragent 或者此形参的 robots.txt 条目存在语法错误,则返回 None。
      
      #request_rate(useragent) 以 named tuple RequestRate(requests, seconds) 的形式从 robots.txt 返回 Request-rate 形参的内容。 如果此形参不存在或不适用于指定的 useragent 或者此形参的 robots.txt 条目存在语法错误,则返回 None。
      
      #site_maps() - 以 list() 的形式从 robots.txt 返回 Sitemap 形参的内容。 如果此形参不存在或者此形参的 robots.txt 条目存在语法错误,则返回 None。
      

    高效爬虫

    python里面共有进程、线程、协程三个层次概念,爬虫就是选择:单线程爬取,单线程+协程爬取,多线程爬取,多线程 + 协程爬取,多进程爬取,多进程 + 协程爬取6种组合方案。

    存在依赖关系的协程之间是不能够被并发执行的,不存在依赖关系的协程之间是能够被并发执行的。

    由于GIL锁的存在,使得线程没法并行执行,只能并发执行。而在并发的情况下,协程的创建、切换开销远远小于线程。所以使用协程而不是使用线程在Python里面是更优的解决方案。

    最高效的爬取方案?答案是: 多进程 + 协程。

    协程的方案肯定要比多线程快,因为协程的切换开销非常之小。而且协程的并发度可以非常高。我们一般开线程也就几十个线程,协程的并发度可以达到999个。但协程的缺点就是没法并行运行。

    所以多进程 + 协程的方案既利用了并行,又利用了并发。完美了利用了多核,同时又让每一个线程的时间片被充分的利用。

  • 相关阅读:
    frida rpc调用维护ios手机脚本
    latex表格调整行距
    latex插图自动在双栏的最top,IEEE期刊格式
    latex插图egin{minipage}强制左移hspace命令
    SYNTHIA-RAND-CITYSCAPES数据集云盘下载
    一种用于多张图片同时缩放比较细节的软件faststone
    shopxo安装插件被限制绑定账号的问题
    ShopXo框架去掉绑定商店的提示
    拓扑排序
    前缀和和差分
  • 原文地址:https://www.cnblogs.com/hermitlee/p/15196699.html
Copyright © 2011-2022 走看看