python模块(七)| python爬虫(一)------urllib模块及其常用方法

python模块(六)------JSON模块及其常用方法

urllib模块
  • 使用之前必需先导入
>>> import urllib.request
  • urlopen()
#由 urlopen()返回的数据就是服务器所返回的原始数据。 这可以是二进制数据(如图片)、纯文本或 HTML 代码等。 HTTP 协议在响应标头中提供了类型信息,这可以通过读取 Content-Type 标头来查看。 如果返回的数据是 HTML,你可以使用 html.parser 模块来解析它

# urllib.request.urlopen(url,data=None,[timeout,]*,context=None)
	# 1、url是网址字符串或一个 Request 对象
	# 2、data 必须是一个对象,用于给出要发送到服务器的附加数据,若不需要发送数据则为 None
	# 3、timeout 为可选参数,用于指定超时时间,单位为秒。如未指定,将使用全局默认超时参数
	# 4、如果给定了 context 参数,则必须是一个 ssl.SSLContext 实例,用于描述各种 SSL 参数
>>> resp = urllib.request.urlopen('http://www.baidu.com')
>>> resp   # 返回一个对象
<http.client.HTTPResponse object at 0x000001F02F4273C8>
>>> resp.url  # 返回请求的网址
'http://www.baidu.com'
>>> resp.headers  # 返回请求头
<http.client.HTTPMessage object at 0x000001F02F43B108>
>>> resp.status   # 返回请求的状态码,200表示请求成功,404、500等等表示请求失败
200
>>> resp.read()   # 返回字节串,没有给参数会返回获取的全部字节串
>>> resp.read(10)  # 返回前10个字节串
b'<!DOCTYPE '
>>> resp.readline()   #  返回一行字节串

# get方法
>>> import urllib.request
>>> import urllib.parse
>>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> url = "http://www.musi-cal.com/cgi-bin/query?%s" % params
>>> with urllib.request.urlopen(url) as f:
...     print(f.read().decode('utf-8'))
...

# post方法
>>> import urllib.request
>>> import urllib.parse
>>> data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> data = data.encode('ascii')
>>> with urllib.request.urlopen("http://requestb.in/xrbl82xr", data) as f:
...     print(f.read().decode('utf-8'))
...
  • Request()
# urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
	# 1、url是网址的字符串。
    # 2、data 必须是一个对象,用于给定发往服务器的附加数据,若无需此类数据则为 None,对于 HTTP POST 请求方法而言,data 应该是标准 application/x-www-form-urlencoded 格式的缓冲区。 urllib.parse.urlencode() 函数的参数为映射对象或二元组序列,并返回一个该编码格式的 ASCII 字符串。在用作 data 参数之前,应将其编码为字节串。
    # 3、headers 应当是一个字典,并将被视同附带了每个键和值作为参数去调用 add_header()。 这通常被用于 "伪装" User-Agent 标头值,浏览器会使用标头值来标识自己 -- 某些 HTTP 服务器只允许来自普通浏览器的请求而不允许来自脚本的请求。 例如,Mozilla Firefox 可能将自己标识为 "Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11",而 urllib 的默认用户代理字符串则是 "Python-urllib/2.6" (在 Python 2.6 中)
	# 接下来的两个参数,只对第三方 HTTP cookie 的处理才有用:
	# 4-1、origin_req_host 应为发起初始会话的请求主机,默认指为``http.cookiejar.request_host(self)`` 。这是用户发起初始请求的主机名或 IP 地址。假设请求是针对 HTML 文档中的图片数据发起的,则本属性应为对包含图像的页面发起请求的主机。
	# 4-2、unverifiable 应该标示出请求是否无法验证,默认值为 False 。所谓无法验证的请求,是指用户没有机会对请求的 URL 做验证。例如,如果请求是针对 HTML 文档中的图像,用户没有机会去许可能自动读取图像,则本参数应为 True。
	# 5、method 应为字符串,标示要采用的 HTTP 请求方法。如果 data 为``None`` 则默认值为 'GET' ,否则为 'POST'
>>> resp = urllib.request.Request('http://www.baidu.com')
>>> resp
<urllib.request.Request object at 0x000001F02F41CCC8>

# Request对象的公开接口,子类可以覆盖所有这些方法
	# 传给构造函数的原始URL,是一个带有setter、getter和deleter的属性,读取full_url属性会返回附带片段(fragment)的初始请求 URL。
	Request.full_url

    # URI 方式。
    Request.type


    # URI 权限,通常是整个主机,但也有可能带有冒号分隔的端口号。
    Request.host

    # 请求的原始主机,不含端口。
    Request.origin_req_host

    # URI 路径。若 Request 使用代理,selector 将会是传给代理的完整 URL。
    Request.selector

    # 请求的数据体,未给出则为 None 。
    Request.data

    # 布尔值,标识本请求是否属于 RFC 2965 中定义的无法验证的情况。
    Request.unverifiable

    # 要采用的 HTTP 请求方法,默认为 None
    Request.method

    # 返回表示 HTTP 请求方法的字符串。如果 Request.method 不为 None ,则返回其值。否则若 Request.data 为 则返回 'GET',不为 None 则返回 'POST' 。只对 HTTP 请求有效。
    Request.get_method()

    # 向请求添加一个标头
    Request.add_header(key, val)

    # 添加一项不会被加入重定向请求的头部信息。
    Request.add_unredirected_header(key, header)

    # 返回本实例是否带有命名头部信息(对常规数据和非重定向数据都会检测)。
    Request.has_header(header)

    # 从本请求实例中移除指定命名的头部信息(对常规数据和非重定向数据都会检测)。
    Request.remove_header(header)

    # 返回构造器中给定的 URL
    Request.get_full_url()

    # 连接代理服务器,为当前请求做准备。 host 和 type 将会取代本实例中的对应值,selector 将会是构造函数中给出的初始 URL。
    Request.set_proxy(host, type)

    # 返回给定头部信息的数据。如果该头部信息不存在,返回默认值。
    Request.get_header(header_name, default=None)

    # 返回头部信息,形式为(名称, 数据)的元组列表。
    Request.header_items()

>>> import urllib.request
>>> req = urllib.request.Request(url='https://localhost/cgi-bin/test.cgi',
...                       data=b'This data is passed to stdin of the CGI')
>>> with urllib.request.urlopen(req) as f:
...     print(f.read().decode('utf-8'))
...
Got Data: "This data is passed to stdin of the CGI"

# 下面是利用 Request 发送``PUT`` 
import urllib.request
DATA = b'some data'
req = urllib.request.Request(url='http://localhost:8080', data=DATA, method='PUT')
with urllib.request.urlopen(req) as f:
    pass
print(f.status)
print(f.reason)

# 添加 HTTP 头部信息
import urllib.request
req = urllib.request.Request('http://www.example.com/')
req.add_header('Referer', 'http://www.python.org/')
req.add_header('User-Agent', 'urllib-example/0.1 (Contact: . . .)')
r = urllib.request.urlopen(req)

import urllib.request
opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
opener.open('http://www.example.com/')
  • urllib.parse----常用的转码函数
# URL转码函数的功能是接收程序数据并通过对特殊字符进行转码并正确编码非 ASCII 文本来将其转为可以安全地用作 URL 组成部分的形式,它们还支持逆转此操作以便从作为 URL 组成部分的内容中重建原始数据

# 使用 %xx 转义符替换 string 中的特殊字符。字母、数字和 '_.-~' 等字符一定不会被转码。在默认情况下,此函数只对 URL 的路径部分进行转码。
urllib.parse.quote(string, safe='/', encoding=None, errors=None)
    # string 可以是 str 或 bytes 对象。
    # 可选的 safe 形参额外指定不应被转码的 ASCII 字符 --- 其默认值为 '/'
    # 可选的 encoding 和 errors 形参指明如何处理非 ASCII 字符
    # encoding 默认为'utf-8'
    # errors默认为'strict',表示不受支持的字符将引发UnicodeEncodeError。如果string为bytes则不可提供encoding和 errors,否则将引发 TypeError
例如: quote('/El Niño/') 将产生 '/El%20Ni%C3%B1o/'# 将 %xx 转义符替换为其单字符等价物
urllib.parse.unquote(string, encoding='utf-8', errors='replace')
    # string 可以是 str 或 bytes 对象
    # 可选的 encoding 和 errors 形参指定如何将以百分号编码的序列解码为 Unicode 字符
    # encoding 默认为 'utf-8'
    # errors 默认为 'replace',表示无效的序列将被替换为占位字符
>>> urllib.parse.unquote("https%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735072616%2F1658823828%5F1265602313%5F1808%5FsProdImgNo%5F1%2Ejpg%2F200")
'https://shp.qpic.cn/ishow/2735072616/1658823828_1265602313_1808_sProdImgNo_1.jpg/200'
>>> urllib.request.unquote("https%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735072616%2F1658823828%5F1265602313%5F1808%5FsProdImgNo%5F1%2Ejpg%2F200")
'https://shp.qpic.cn/ishow/2735072616/1658823828_1265602313_1808_sProdImgNo_1.jpg/200'

# 类似于quote(),但还会使用加号来替换空格,原始字符串中的加号会被转义,除非它们已包括在safe中。它也不会将safe的默认值设为 '/'
urllib.parse.quote_plus(string, safe='', encoding=None, errors=None)
例如: quote_plus('/El Niño/') 将产生 '%2FEl+Ni%C3%B1o%2F'# 类似于 unquote(),但还会将加号替换为空格,string 必须为 str
urllib.parse.unquote_plus(string, encoding='utf-8', errors='replace')
例如: unquote_plus('/El+Ni%C3%B1o/') 将产生 '/El Niño/'# 类似于 quote(),但是接受 bytes 对象而非 str,并且不执行从字符串到字节串的编码  
urllib.parse.quote_from_bytes(bytes, safe='/')
例如: quote_from_bytes(b'a&\xef') 将产生 'a%26%EF'# 将 %xx 转义符替换为其单八位等价物,并返回一个 bytes 对象,string 可以是 str 或 bytes 对象,如果它是 str,则 string 中未转义的非 ASCII 字符会被编码为 UTF-8 字节串。
urllib.parse.unquote_to_bytes(string)
例如: unquote_to_bytes('a%26%EF') y将产生 b'a&\xef'# 将一个包含有 str 或 bytes 对象的映射对象或二元组序列转换为以百分号编码的 ASCII 文本字符串。 如果所产生的字符串要被用作 urlopen() 函数的 POST 操作的 data,则它应当被编码为字节串,否则它将导致 TypeError。
# 结果字符串是一系列 key=value 对,由 '&' 字符进行分隔,其中 key 和 value 都已使用 quote_via 函数转码。 在默认情况下,会使用 quote_plus() 来转码值,这意味着空格会被转码为 '+' 字符而 '/' 字符会被转码为 %2F,另一个可以作为 quote_via 传入的替代函数是 quote(),它将把空格转码为 %20 并且不编码 '/' 字符,当使用二元组序列作为 query 参数时,每个元组的第一个元素为键而第二个元素为值。 值元素本身也可以为一个序列,在那种情况下,如果可选的形参 doseq 的值为 True,则每个键的值序列元素生成单个 key=value 对(以 '&' 分隔)。 被编码的字符串中的参数顺序将与序列中的形参元素顺序相匹配。
urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus)
>>> urllib.parse.urlencode({"name":"zs"})
'name=zs'
>>> data = urllib.parse.urlencode({"name":"zs","age":25})
>>> data
'name=zs&age=25'
>>> data.encode('ascii')
b'name=zs&age=25'

# 将一个 URL 解析为六个部分,返回一个包含 6 项的 named tuple
urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
>>> from urllib.parse import urlparse
>>> urlparse("scheme://netloc/path;parameters?query#fragment")
ParseResult(scheme='scheme', netloc='netloc', path='/path;parameters', params='',
            query='query', fragment='fragment')
>>> o = urlparse("http://docs.python.org:80/3/library/urllib.parse.html?"
...              "highlight=params#url-parsing")
>>> o
ParseResult(scheme='http', netloc='docs.python.org:80',
            path='/3/library/urllib.parse.html', params='',
            query='highlight=params', fragment='url-parsing')
>>> o.scheme
'http'
>>> o.netloc
'docs.python.org:80'
>>> o.hostname
'docs.python.org'
>>> o.port
80
>>> o._replace(fragment="").geturl()
'http://docs.python.org:80/3/library/urllib.parse.html?highlight=params'

>>> from urllib.parse import urlparse
>>> urlparse('//www.cwi.nl:80/%7Eguido/Python.html')
ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> urlparse('www.cwi.nl/%7Eguido/Python.html')
ParseResult(scheme='', netloc='', path='www.cwi.nl/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> urlparse('help/Python.html')
ParseResult(scheme='', netloc='', path='help/Python.html', params='',
            query='', fragment='')

>>> from urllib.parse import urlparse
>>> u = urlparse('//www.cwi.nl:80/%7Eguido/Python.html')
>>> u
ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> u._replace(scheme='http')
ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')

# 合并url
urllib.parse.urljoin(base, url, allow_fragments=True)
>>> from urllib.parse import urljoin
>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
'http://www.cwi.nl/%7Eguido/FAQ.html'
  • robots协议
# 可以读取、解析和回答关于 url 上的 robots.txt 文件的问题的方法
class urllib.robotparser.RobotFileParser(url='')

# 设置指向 robots.txt 文件的 URL。
set_url(url)

# 读取 robots.txt URL 并将其输入解析器。
read()

# 解析行参数。
parse(lines)

# 如果允许 useragent 按照被解析 robots.txt 文件中的规则来获取 url 则返回 True。
can_fetch(useragent, url)

# 返回最近一次获取 robots.txt 文件的时间。 这适用于需要定期检查 robots.txt 文件更新情况的长时间运行的网页爬虫。
mtime()

# 将最近一次获取 robots.txt 文件的时间设置为当前时间。
modified()

# 为指定的 useragent 从 robots.txt 返回 Crawl-delay 形参。 如果此形参不存在或不适用于指定的 useragent 或者此形参的 robots.txt 条目存在语法错误,则返回 None。
crawl_delay(useragent)

# 以 named tuple RequestRate(requests, seconds) 的形式从 robots.txt 返回 Request-rate 形参的内容。 如果此形参不存在或不适用于指定的 useragent 或者此形参的 robots.txt 条目存在语法错误,则返回 None。
request_rate(useragent)

# 以 list() 的形式从 robots.txt 返回 Sitemap 形参的内容。 如果此形参不存在或者此形参的 robots.txt 条目存在语法错误,则返回 None。
site_maps()

>>> import urllib.robotparser
>>> rp = urllib.robotparser.RobotFileParser()
>>> rp.set_url("http://www.musi-cal.com/robots.txt")
>>> rp.read()
>>> rrate = rp.request_rate("*")
>>> rrate.requests
3
>>> rrate.seconds
20
>>> rp.crawl_delay("*")
6
>>> rp.can_fetch("*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco")
False
>>> rp.can_fetch("*", "http://www.musi-cal.com/")
True

python爬虫(二)------requests模块及其常用方法-get()、post()

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值