爬虫技术(1) 前置知识与架构

1. requests 库的使用

安装

pip install requests

发送请求

(1)请求方式

  • Get 查看资源
  • POST 增加资源
  • PUT 修改资源
  • PATCH 少量修改资源
  • DELETE 删除资源
  • HEAD 查看响应头
  • OPTIONS 查看可用的请求方法

(2)请求api

  • get 方式 后面跟拼接参数: requests.get(url, params={'key1':'value1'})
  • 表单参数提交: requests.post(url, data={'key1':'value1','key2':'value2'})
  • json 参数提交 requests.post(url, json={'key1':'value1','key2':'value2'})
  • 提交文件 requests.post(url, files={'file':open('sss.csv','rb')})

(3)请求异常处理(异常放在requests.exceptions包内)

  1. 请求超时处理:except exceptions.Timeout
    requests.get(url, timeout=10)
  2. 错误码异常处理 except exceptions.HTTPError
    如果响应的状态码不为200,response.raise_for_status() 会抛出状态码异常:response.raise_for_status()
import requests
from requests.exceptions import Timeout, ConnectionError, RequestException,.HTTPError
 
try:
    resp = requests.get('http://httpbin.org/get', timeout=0.5)
    print(resp.status_code)
except Timeout: # 访问超时的错误
    print('Timeout')
except ConnectionError: # 网络中断连接错误
    print('Connect error')
except RequestException: # 父类错误
    print('Error')
except HTTPError: # 错误码
    print('响应状态非200')

Demo

//伪造头信息
headers = {"Host":" music.163.com",

"User-Agent":" Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",

}
requests.get(url,headers = headers)

#  文件上传
files = {'file' : open('logo.gif','rb')}
resp = requests.post('http://httpbin.org/post', files=files)

解析响应

1.响应状态码:

1XX:消息

2XX 请求成功:
200 返回响应成功 201 资源建立成功 204 成功响应,无返回  

3XX 重定向:
301 永久移动 302 暂时移动 304 上次的get请求访问过的内容

4XX 客户端错误:
400 请求有问题 401 认证问题 403 权限不足,服务器拒绝执行 404 页面不存在

5XX 服务器端错误:
500 服务器端有bug 501 无法识别请求的方法502 网关错误 503 服务不可用

2. 响应的api

基本api

  • status_code 状态码

  • reason 响应情况

  • headers 获取响应头

  • url( 响应的地址

  • request 获得响应对应的请求的对象,有headers 和 body

内容相关的api:

  • content() 读取二进制内容 常用于图片下载
  • text() 解析为解码后的字符串(可以修改requests.encoding = 'utf-8' 默认是utf-8)
  • json() 将json格式的响应解析为python中的字典

demo

一.图片下载
from contextlib import closing
url = 'http://pic.58pic.com/58pic/16/42/96/56e58PICAu9_1024.jpg'
 #伪造头信息
 headers = {'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:51.0) 
Gecko/20100101 Firefox/51.0'}
#关闭流的方式发送请求
 with closing(requests.get(url,headers=headers)) as response:
 with open('demo.jpg','wb') as f:
#每128个字节写入一次文件
        for chunk in response.iter_content(128):
            f.write(chunk)

二、事件钩子(Event Hooks) 发送请求,在获取响应时回调钩子函数

import requests
def func(response,*args,**kws):
    pass
requests.get(url,hooks=dict(response=func))

使用进阶

(1) HTTP认证

  1. 基本认证,验证账号与密码
    requests.get(url,auth=(name,password))

  2. OAUTH认证

from requests.auth import AuthBase

class GitHubAuth(AuthBase):
def __init__(self, token):
  self.token= token
def __call__(self,r):
#request 加headers
  r.headers['Authorization'] = '  '.join(['token', self.token])
def oauth_advanced():
  #传入access token
auth = GithubAuth('dddsfsdfsdfasf')
response = requests.get(url,auth = auth)
  1. 代理设置

有些网站会限制 IP 访问频率,超过频率就断开连接。这个时候我们就需要使用到代理,我们可以通过为任意请求方式提供proxies参数来配置单个请求。

import requests
 
proxies = {
    "http": "http://10.10.1.10:3128",
    "https": "http://10.10.1.10:1080",
}
resp = requests.get('http://www.baidu.com', proxies=proxies)
print(resp.status_code)

也可以通过环境变量 HTTP_PROXYHTTPS_PROXY 来配置代理。
有些代理需要加上用户名和密码的,代理可以使用http://user:password@host/语法,比如:

proxies = {
    "http": "http://user:[email protected]:3128/",
}

2. xpath的使用

安装

pip install lxml

Demo

from lxml import etree

# 字符串读取html
html_str = '''  

'''

html = etree.HTML(html_str)
#也可以从文件读取html html = etree.parse('hello.html') 

res = html.xpath("//div/ul/li[@class='item-0']/a")

for e in res:
    print(e.text)
    print(e.get("href"))

xpath语法

1. 获取 
  • 标签的所有 class result = html.xpath('//li/@class') print result 运行结果: ['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0'] 2. 获取
  • 标签下 href 为 link1.html 的 标签 result = html.xpath('//li/a[@href="link1.html"]') print result 运行结果 [] 3. 获取
  • 标签下的所有 标签 不能这样写:result = html.xpath('//li/span') 因为 / 是用来获取子元素的,而 并不是
  • 的子元素,所以,要用双斜杠 result = html.xpath('//li//span') print result 运行结果 [] 4. 获取
  • 标签下的所有 class,不包括
  • result = html.xpath('//li/a//@class') print result 运行结果 ['blod'] 5. 获取最后一个
  • 的 href result = html.xpath('//li[last()]/a/@href') print result 运行结果 ['link5.html'] 6. 获取倒数第二个元素的内容 result = html.xpath('//li[last()-1]/a') print result[0].text 运行结果 fourth item 7. 获取 class 为 bold 的标签名 result = html.xpath('//*[@class="bold"]') print result[0].tag 运行结果 span
  • 进阶用法

    # 对节点进行xpath查询 处理字段缺失
    tables = html.xpath("//div[@class='indent']//table")
    for table in tables:
                score = table.xpath(".//span[@class='rating_nums']")[0].text
                description = "暂无简介"
                node = table.xpath(".//span[@class='inq']")
                if node:
                    description = node[0].text
    
    # 获取某节点内所有文字内容
    # 
  • sss second item ss
  • res = html.xpath('//li')[1] text = res.xpath('string(.)') print(l1) # 结果: sss second item ss

    进阶

    MongoDB的使用 设置下载缓存和实现多进程任务

    教程

    爬虫教程

    你可能感兴趣的:(爬虫技术(1) 前置知识与架构)