爬虫(一)—— 请求库(一)requests请求库

requests请求库

爬虫:爬取、解析、存储

1、请求

一、基本有用的参数

# 1.请求的url
https://www.cnblogs.com/linagcheng/

# 2.请求的方法
post,get,header...

# 3.请求头须要携带参数
Cookie
User-Agent    # 说明本身是浏览器
Refer    # 从哪一个网站跳过来

# 4.请求体(formdata)——post请求才有
密码可能加密,可使用错误的用户名+正确的密码,获取加密过的密码

二、请求url编码

# 1.url编码 --- 参数为中文,实际url使用的是原参数编码过的数据
# 例如:https://www.baidu.com/s?wd=汽车
#   其实是:https://www.baidu.com/s?wd=%E6%B1%BD%E8%BD%A6

from urllib.parse import urlencode

keyword = input(">>>:")
res = urlencode({'wd':keyword})
print(res)   # wd=%E6%B1%BD%E8%BD%A6

url = 'https://www.baidu.com/s?'+res
print(url)

三、headers参数——添加请求头中的数据

import requests

response = requests.get(url='https://www.baidu.com/s?wd=%E6%B1%BD%E8%BD%A6',
                        headers={
                            'User-Agent':Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36
                        },
                       )

四、params参数——不用urlencode

keyword = input('>>>:').strip()
response = requests.get(url='https://www.baidu.com/s?',
                        params={
                          'wd':keyword,    # url中的参数,不用将中文进行编码
                          'pn':2,        # 页码                    
                        },
                        headers={
                            'User-Agent':Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36
                        },
                       )

五、requests的其余参数

cookies    # cookie 既能够写在requests的cookie中,也能够写在header中的Cookie中
allow_redirects:True/False  # requests遇到location也会自动跳转,allow_redirects能够修改是否跳转

六、get方法与post方法

requests.get(url='....', headers={...}, cookie={...}, params={...})

requests.post(url='......', headers={...}, cookie={...}, data={...})

七、请求的总体流程

1.GET方式请求
可能会返回一个token,用于第二次请求携带

2.POST请求

2、响应

一、基本数据

# 响应状态码
200   成功
300   重定向

# 响应头
Location
Cookie

# 响应体
html   # 正则筛选数据
json   # 能够反序列化获得内容
二进制   # 以rb方式打开文件,写入文件

二、响应的参数

response.status_code    # 响应状态码

response.text    # 文本,获取页面HTML字符串
response.content  # 二进制数据,能够写入文件

response.history     # 获取页面跳转前的内容

response.cookies.get_dict()   # 获取响应的cookie,并转换成字典

response.encode ='gbk'  # 指定响应内容的编码

三、响应数据

(1)文本数据
response.text
(2)二进制数据
# 1.数据量过大时,至关于一次大数据放入内存,致使内存占用过大
with open('b.mp4','wb') as f:
    f.write(response.content)

# 2.终极版:使用二进制流解决内存占用过大问题
with open('b.mp4','wb') as f:
    for line in response.iter_content():     # response.iter_content() 获得一个迭代器对象
        f.write(line)    # 逐行写数据
(3)json格式数据
# 解析json格式字符串
res = response.json()    # 至关于json.loads(response.text),反序列化

3、简单爬虫

一、普通爬取

import requests
import re

# 1.经过requests来获取爬取的页面
def get_page(url):
    try:
        response=requests.get(url)
        if response.status_code == 200:
            return response.text
    except Exception:
        pass

# 2.在获取到页面之后,从页面中解析出须要的数据:例如 能够获取视频详情页面的url
def parse_index(index_page):
    urls = re.findall('',index_page,re.S)    # re.S 去掉换行
    for url in urls:
        if not url.startswith('http'):
            url = 'http://www.baidu.com' + url
        yield url
    

# 3.解析完之后,根据解析所得数据获取更深层次的数据:例如根据详情页面的url,获取视频的url
def get_detail_page():
    # 正则匹配,从详情页面中获取视屏的url
    pass

# 4.获取根据视频的url下载视频,保存在文件中
def get_movie(url):
    try:    # 可能视频请求不到会报异常
        response = requests.get(url)
        if response.status_code == 200:

            with open('xxx.mp4','wb') as f:
                f.write(response.content)
                print('%s如今成功'%url)
    except Exception:
        pass


if __name__ == "__main__":
    pass

二、并发爬取

import requests
import re
import hashlib
import time
from concurrent.futures import ThreadPoolExecutor

pool=ThreadPoolExecutor(50)
movie_path=r'C:\mp4'

def get_page(url):
    try:
        response=requests.get(url)
        if response.status_code == 200:
            return response.text
    except Exception:
        pass

def parse_index(index_page):
    index_page=index_page.result()
    urls=re.findall('class="items".*?href="(.*?)"',index_page,re.S)
    for detail_url in urls:
        if not detail_url.startswith('http'):
            detail_url='http://www.xiaohuar.com'+detail_url
        pool.submit(get_page,detail_url).add_done_callback(parse_detail)# 提交任务,成功回调

def parse_detail(detail_page):
    detail_page=detail_page.result()   # 回调函数返回的是一个对象,从 对象.result() 中获取数据
    l=re.findall('id="media".*?src="(.*?)"',detail_page,re.S)
    if l:
        movie_url=l[0]
        if movie_url.endswith('mp4'):
            pool.submit(get_movie,movie_url)   # 提交任务,成功回调

def get_movie(url):
    try:
        response=requests.get(url)  # 回调函数返回的是一个对象,从 对象.result() 中获取数据
        if response.status_code == 200:
            m=hashlib.md5()
            m.update(str(time.time()).encode('utf-8'))
            m.update(url.encode('utf-8'))
            filepath='%s\%s.mp4' %(movie_path,m.hexdigest())
            with open(filepath,'wb') as f:
                f.write(response.content)
                print('%s 下载成功' %url)
    except Exception:
        pass

def main():
    base_url='http://www.xiaohuar.com/list-3-{page_num}.html'
    for i in range(5):
        url=base_url.format(page_num=i)
        pool.submit(get_page,url).add_done_callback(parse_index) # 提交任务,成功回调

if __name__ == '__main__':
    main()

4、requests高级用法

一、SSL认证

# https的网站是须要带证书的

# 访问方式:
# 1.不验证证书,而且去掉警告。大部分网站是可带可不带证书
import requests
from requests.packages import urllib3
urllib3.disable_warnings()    # 关闭警告
respone=requests.get('https://www.12306.cn',verify=False)   # verify=False不验证证书

# 2.带上证书。部分网站强制携带证书访问,例如:内部网站,金融网站
import requests
respone=requests.get('https://www.12306.cn',
                     cert=('/path/server.crt',
                           '/path/key'))    # 证书的目录,key的目录,能够冲网站上下载
print(respone.status_code)

二、使用IP代理

# 一个网站的访问频率太高,可能致使当前IP被封
# 使用代理访问网站——先把请求转发给代理主机,而后由代理主机访问目标网站

# 使用方式
# 1.http代理    ——   转发http协议 
import requests
response = requests.get('https://www.baidu.com',
                        proxies={
                            'http':'http://代理主机ip:port',
                            'https':'https://代理主机ip:port',
                        })

# 2.sock代理    ——   不只能够转发http协议,亦能够转发ftp协议等其余协议
import requests
response = requests.get('https://www.baidu.com',
                        proxies={
                            'sock':'http://代理主机ip:port',
                        })

三、超时设置

# 不设置超时时间,会一直发请求,直到有返回;设置超时时间,当发请求时间超出限制,直接抛出异常

import requests
respone=requests.get('https://www.baidu.com', timeout=0.0001)

四、认证设置(通常用不到,公司内网用的多)

# 例如访问某个加密过的网站,先要验证用户名密码才能访问。例如:加密的博客,若是博客密码不对,没法获取博客内容

# HTTPBasicAuth是基本的加密,通常使用自定义的加密算法
# 要认证须要知道加密算法,或者手动认证获取cookie
import requests
from requests.auth import HTTPBasicAuth
res=requests.get('xxx',auth=HTTPBasicAuth('user','password'))
print(res.status_code)

# HTTPBasicAuth能够简写为以下格式   ——————  auth参数
import requests
res=requests.get('xxx',auth=('user','password'))
print(res.status_code)

五、异常处理

# 异常处理

import requests
from requests.exceptions import * # 能够查看requests.exceptions获取异常类型

try:
    r=requests.get('http://www.baidu.com',timeout=0.00001)
except ReadTimeout:
    print('===:')
except RequestException:
    print('Error')

六、上传文件

# post方法中有一个 files参数

import requests
files={'file':open('a.jpg','rb')}    # 字典
respone=requests.post('http://httpbin.org/post',files=files)
print(respone.status_code)

5、session方法(建议使用)

import requests

session = requests.session()
sesssion.get()    # 当发请求时,就会返回一个cookie,session方法获得的对象能够保存这个cookie,不用手动获取cookie用来第二次请求
session.post()

6、selenium模块

相关文章
相关标签/搜索