爬虫入门

urllib

urllib.request.urlopen()

可以直接得到网页html信息

>>> urlopen(url1).read()
# 格式化显示html代码
>>> urlopen(url1).read().encode("utf-8")
from urllib.request import urlopen
from urllib import parse

# urllib.request.urlopen(url, data=None, [timeout, ] *, cafile=None, capath=None, cadefault=False, context=None)
# url 为目标地址
# data 添加的数据,如果要传,必须传 bytes(字节流)类型的。如果它是字典,可以先用 urllib.parse 模块里的 urlencode() 编码。
# timeout 最大时间,否则进入超时处理

url = "http://httpstat.us"
data = bytes(parse.urlencode({'word': 'hello'}), encoding='utf-8')
info = urlopen(url1, data=data, timeout=0.01)
print(info.status)
print(info.getheaders())

输出结果

200
[('Server', 'nginx'), ('Date', 'Tue, 08 Oct 2019 13:13:02 GMT'), ('Content-Type', 'text/html'), ('Content-Length', '17168'), ('Connection', 'close'), ('Vary', 'Accept-Encoding'), ('Cache-Control', 'private'), ('X-Powered-By', 'ASP.NET'), ('X-Cache-Time', '10m')]

超时,即获取网页时间大于timeout

from urllib.request import urlopen
from urllib import parse
from urllib.error import URLError

try:
    response = urlopen('https://www.python.org', timeout=0.01)
    print(response.read().encode("utf-8"))
except URLError as e:
	# 输出e的原因
    print(e.reason)

输出结果

time out

urllib.request.Request()

class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)

# 第一个参数 url 用于请求 URL,这是必传参数,其他都是可选参数。
# 第二个参数 data 如果要传,必须传 bytes(字节流)类型的。如果它是字典,可以先用 urllib.parse 模块里的 urlencode() 编码。
# 第三个参数 headers 是一个字典,它就是请求头,我们可以在构造请求时通过 headers 参数直接构造,也可以通过调用请求实例的 add_header() 方法添加。
# 第五个参数 unverifiable 表示这个请求是否是无法验证的,默认是 False,意思就是说用户没有足够权限来选择接收这个请求的结果。例如,我们请求一个 HTML 文档中的图片,但是我们没有自动抓取图像的权限,这时 unverifiable 的值就是 True。
# 第六个参数 method 是一个字符串,用来指示请求使用的方法,比如 GET、POST 和 PUT 等。
from urllib.request import Request
from urllib.request import urlopen

url = 'https://www.python.org'
# 将url放入Request对象中
request = Request(url)
# 利用urlopen获取request
response = urlopen(request)
print(response.read())

添加代理,数据,method

from urllib.request import Request
from urllib.request import urlopen
from urllib import parse

url = 'http://httpbin.org/post'
headers = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)', 'Host': 'httpbin.org'}
data = bytes(parse.urlencode({'word': 'hello'}), encoding='utf-8')

request = Request(url, data=data, headers=headers, method='POST')
response = urlopen(request)
print(response.read().decode("utf-8"))

headers 也可以用 add_header 方法来添加

request.add_header('User-Agent', 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)')
request.add_header('Host', 'httpbin.org')

urllib.error

from urllib import request, error
try:
    response = request.urlopen('https://cuiqingcai.com/index.htm')
# HTTPError是URLError的子类,先捕获子类,再捕获父类,最后else处理
except error.HTTPError as e:
    print(e.reason)
    print(e.code)
except error.URLError as e:
    print(e.reason)
else:
    print("Success")

有时候e.reason不全是字符串

from urllib import request, error
try:
    response = request.urlopen('https://cuiqingcai.com/index.htm')
except error.URLError as e:
    print(type(e.reason))
    print(e.reason)

try:
    response = request.urlopen("https://www.baidu.com", timeout=0.01)
except error.URLError as e:
    print(type(e.reason))
    print(e.reason)

输出结果

<class 'str'>
Not Found
<class 'socket.timeout'>
timed out

urllib.parse.urlparse

from urllib.parse import urlparse

result = urlparse('http://www.baidu.com/index.html;user?id=5#comment')
print(type(result))
print(result)
<class 'urllib.parse.ParseResult'>
ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5', fragment='comment')
符号:// 前面的就是 scheme,代表协议;
符号/   前面便是 netloc,即域名,后面是 path,即访问路径;
符号;  后面是 params,代表参数;问号?后面是查询条件 query,一般用作 GET 类型的 URL;
符号#   后面是锚点,用于直接定位页面内部的下拉位置。

urlparse API用法

urllib.parse.urlparse(urlstring, scheme='',allow_fragments=True)
1. urlstring:这是必填项,即待解析的 URL。
2. scheme:它是默认的协议(比如 http 或 https 等)
3. allow_fragments:即是否忽略 fragment。如果它被设置为 False,fragment 部分就会被忽略,它会被解析为 path、parameters 或者 query 的一部分,而 fragment 部分为空

设置allow_fragments为False

result = urlparse('http://www.baidu.com/index.html;user?id=5#comment', allow_fragments=False)
print(result)

输出结果

ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5#comment', fragment='')

requests

get

urllib 库中的 urlopen 方法实际上是以 GET 方式请求网页,而 requests 中相应的方法就是 get 方法

import requests

r = requests.get("http://www.baidu.com")
print(r.text)

# <class 'str'>
print(type(r.text))
print(r.status_code)

# <class 'dict'>
print(type(r.json())
print(r.json())
import requests  

r = requests.get('http://httpbin.org/get')  
print(r.text)

附加额外的信息

import requests  

data = {  
    'name': 'germey',  
    'age': 22  
}  
r = requests.get("http://httpbin.org/get", params=data)  
print(r.text)
请求链接变为
http://httpbin.org/get?age=22&name=germey

正则表达式re

re.match

match 方法会尝试从字符串的起始位置匹配正则表达式,如果匹配,就返回匹配成功的结果;如果不匹配,就返回 None

import re

content = 'Hello 123 4567 World_This is a Regex Demo'
print(len(content))
result = re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}', content)
print(result)
# 分组
print(result.group())
# 匹配的字符串开始和结束的位置
print(result.span())

输出结果

41
<_sre.SRE_Match object; span=(0, 25), match='Hello 123 4567 World_This'>
Hello 123 4567 World_This
(0, 25)
import re

content = 'Hello 1234567 World_This is a Regex Demo'
# ()分组,多个()多个分组
result = re.match('^Hello\s(\d+)\sWorld', content)
print(result)
print(result.group())
print(result.group(1))
print(result.span())
<_sre.SRE_Match object; span=(0, 19), match='Hello 1234567 World'>
Hello 1234567 World
1234567
(0, 19)
result = re.match('^Hello\s(\d+)(\d+)\sWorld', content)
# 输出结果:123456 7
print(result.group(1), result.group(2))
import re

content = 'Hello 123 4567 World_This is a Regex Demo'

# .表示任意一个字符,.*表示任意多个任意字符,$标志单行结尾
result = re.match("^Hello.*Demo$", content)
print(result.group())
print(result.span())

贪婪匹配
尽可能地多匹配字符

import re

content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^He.*(\d+).*Demo$', content)
# Hello 1234567 World_This is a Regex Demo
print(result)
# 7
print(result.group(1))

非贪婪匹配
尽可能地匹配少的字符,添加

result = re.match("^Hello.*?(\d+).*Demo$", content)
# 1234567
print(result.group(1))

修饰符

import re

content = '''Hello 1234567 World_This
is a Regex Demo
'''
result = re.match('^He.*?(\d+).*?Demo$', content)
print(result.group(1))

输出结果会报错,因为匹配不会匹配到换行符

Traceback (most recent call last):
  File "____________.py", line 7, in <module>
    print(result.group(1))
AttributeError: 'NoneType' object has no attribute 'group'

加上修饰符re.S

# 1234567
result = re.match('^He.*?(\d+).*?Demo$', content, re.S)

在这里插入图片描述

转义匹配

特殊字符加反斜杠 \

re.search

match 方法是从字符串的开头开始匹配的,一旦开头不匹配,那么整个匹配就失败了。
search方法在匹配时会扫描整个字符串,然后返回第一个成功匹配的结果。

import re

content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'
# re.match
result = re.match('Hello.*?(\d+).*?Demo', content)
# None
print(result)

# re.search
result = re.search('Hello.*?(\d+).*?Demo', content)
# <re.Match object; span=(13, 53), match='Hello 1234567 World_This is a Regex Demo'>
print(result)
import re

html = '''<div id="songs-list">
<h2 class="title"> 经典老歌 </h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2"> 一路上有你 </li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐"> 沧海一声笑 </a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦"> 往事随风 </a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond"> 光辉岁月 </a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳"> 记事本 </a></li>
<li data-view="5">
<a href="/6.mp3" singer="邓丽君"> 但愿人长久 </a>
</li>
</ul>
</div>'''

result = re.search('<li.*?singer="(.*?)">(.*?)</a>', html, re.S)
if result:
    # " 沧海一声笑 "前后各有一个空格,需要处理掉
    print(result.group(1), result.group(2), sep='')
    # 处理空格
    singer = result.group(2).replace(' ', '')
    print(len(singer), singer)
输出结果为
任贤齐 沧海一声笑

如果不加re.S,结果为

beyond 光辉岁月

re.findall





















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值