python学习笔记-爬虫01

#============================爬虫准备工作============================
# 参考资料
    # python网络数据采集, 图灵工业出版
    # 精通Python爬虫框架Scrapy, 人民邮电出版社
    # [Python3网络爬虫](http://blog.csdn.net/c406495762/article/details/72858983)
    # [Scrapy官方教程](http://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html)
# 前提知识
    # url
    # http协议
    # web前端,html, css, js
    # ajax
    # re, xpath
    # xml
    
#============================爬虫简介============================
# 爬虫定义:网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),
        #是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。
        #另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。
# 两大特征
    # 能按作者要求下载数据或者内容
    # 能自动在网络上流窜
# 三大步骤:
    # 下载网页
    # 提取正确的信息
    # 根据一定规则自动跳到另外的网页上执行上两步内容
# 爬虫分类
    # 通用爬虫
    # 专用爬虫(聚焦爬虫)
# Python网络包简介
    # Python2.x:urllib, urllib2, urllib3, httplib, httplib2, requests
    # Python3.x: urllib, urllib3, httplib2, requests
    # python2: urllib和urllib2配合使用,或者requests
    # Python3: urllib,requests
 
#==========================urllib=========================
# 包含模块
    # urllib.request: 打开和读取urls
    # urllib.error: 包含urllib.request产生的常见的错误,使用try捕捉
    # urllib.parse:  包含解析url的方法
    # urllib.robotparse: 解析robots.txt文件
    # 案例v1:

    from urllib import request
    url = "http://jobs.zhaopin.com/..."
    # 打开相应url并把相应页面作为返回
    rsp = request.urlopen(url)
    # 把返回结果读取出来
    # 读取出来内容类型为bytes
    html = rsp.read()
    # 如果想把bytes内容转换成字符串,需要解码
    html = html.decode("utf-8")

# 网页编码问题解决
    # chardet 可以自动检测页面文件的编码格式,但是,可能有误
    # 需要安装, conda install chardet
    # 案例v2片段:

    #利用 chardet自动检测
    cs = chardet.detect(html)
    # 使用get取值保证不会出错
    html = html.decode(cs.get("encoding", "utf-8"))

# urlopen 的返回对象
    # geturl: 返回请求对象的url
    # info: 请求反馈对象的meta信息
    # getcode:返回的http code    
    
# request.data 的使用
    # 访问网络的两种方法
        # get: 
            # 利用参数给服务器传递信息,
            # 参数为dict,然后用parse编码
            # 案例v4片段:

from urllib import request, parse

url = 'http://www.baidu.com/s?'
wd = input("Input your keyword:")

# 要想使用data, 需要使用字典结构
qs = {"wd": wd}
# 转换url编码
qs = parse.urlencode(qs)
fullurl = url + qs
# 如果直接用可读的带参数的url,是不能访问的
#fullurl = 'http://www.baidu.com/s?wd=大熊猫'
rsp = request.urlopen(fullurl)
html = rsp.read()

        # post
            # 一般向服务器传递参数使用
            # post是把信息自动加密处理
            # 我们如果想使用post信息,需要用到data参数
            # 使用post,意味着Http的请求头可能需要更改:
                # Content-Type: application/x-www.form-urlencode
                # Content-ength: 数据长度
                # 简而言之,一旦更改请求方法,请注意其他请求头部信息相适应
            # urllib.parse.urlencode可以将字符串自动转换成上面的
            # 案例v5:经典案例:

'''
利用parse模块模拟post请求
分析百度词典
分析步骤:
1. 打开F12
2. 尝试输入单词girl,发现每敲一个字母后都有请求
3. 请求地址是 http://fanyi.baidu.com/sug
4. 利用NetWork-All-Hearders,查看,发现FormData的值是 kw:girl
5. 检查返回内容格式,发现返回的是json格式内容==>需要用到json包
'''
from urllib import request, parse
# 负责处理json格式的模块
import json
'''
大致流程是:
1. 利用data构造内容,然后urlopen打开
2. 返回一个json格式的结果
3. 结果就应该是girl的释义
'''
baseurl = 'http://fanyi.baidu.com/sug'
# 存放用来模拟form的数据一定是dict格式
data = {
    # girl是翻译输入的英文内容,应该是由用户输入,此处使用硬编码
    'kw': 'girl'
}
# 需要使用parse模块对data进行编码
data = parse.urlencode(data).encode("utf-8")
rsp = request.urlopen(baseurl, data=data)
json_data = rsp.read().decode('utf-8')
# 把json字符串转化成字典
json_data = json.loads(json_data)
print(type(json_data))
print(json_data)
for item in json_data['data']:
    print(item['k'], "--", item['v'])

            # 为了更多的设置请求信息,单纯的通过urlopen函数已经不太好用了
            # 需要利用request.Request 类
                        # 构造一个Request的实例
                        # 我们需要构造一个请求头,请求头部应该至少包含传入的数据的长度
                        # request要求传入的请求头是一个dict格式
                        headers = {
                            # 因为使用post,至少应该包含content-length 字段
                            'Content-Length':len(data)
                        }

                        # 有了headers,data,url,就可以尝试发出请求了
                        req = request.Request(url=baseurl, data=data, headers=headers)
                        # 因为已经构造了一个Request的请求实例,则所有的请求信息都可以封装在Request实例中
                        rsp = request.urlopen(req)

# urllib.error
    # URLError产生的原因:
        # 没网
        # 服务器链接失败
        # 知不道制定服务器
        # 是OSError的子类
    # HTTPError, 是URLError的一个子类
        # 案例v8      

from urllib import request, error
try:
    req = request.Request(url)
    rsp = request.urlopen(req)
    html = rsp.read().decode()
    print(html)
except error.HTTPError as e:
    print("HTTPError: {0}".format(e.reason))
    print("HTTPError: {0}".format(e))
except error.URLError as e:
    print("URLError: {0}".format(e.reason))
    print("URLError: {0}".format(e))
except Exception as e:
    print(e)

    # 两者区别:
        # HTTPError是对应的HTTP请求的返回码错误, 如果返回错误码是400以上的,则引发HTTPError
        # URLError对应的一般是网络出现问题,包括url问题
        # 关系区别: OSError-URLError-HTTPError
        
# UserAgent 
    # UserAgent: 用户代理,简称UA, 属于heads的一部分,服务器通过UA来判断访问者身份
    # 常见的UA值,使用的时候可以直接复制粘贴,也可以用浏览器访问的时候抓包
        
            1.Android

            Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19
            Mozilla/5.0 (Linux; U; Android 4.0.4; en#gb; GT#I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
            Mozilla/5.0 (Linux; U; Android 2.2; en#gb; GT#P1000 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1

            2.Firefox

            Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0
            Mozilla/5.0 (Android; Mobile; rv:14.0) Gecko/14.0 Firefox/14.0

            3.Google Chrome

            Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36
            Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19

            4.iOS

            Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3
            Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A101a Safari/419.3

    # 设置UA可以通过两种方式:
        # heads
        # add_header

        # 使用head方法伪装UA
        # headers = {}
        # headers['User-Agent'] = 'Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3'
        # req = request.Request( url, headers=headers)

        # 使用add_header方法
        req = request.Request(url)
        req.add_header("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36")

        # 正常访问
        rsp = request.urlopen( req )
        html = rsp.read().decode()
        print(html)
        
# ProxyHandler处理(代理服务器)
    # 使用代理IP,是爬虫的常用手段
    # 获取代理服务器的地址:
        # www.xicidaili.com
        # www.goubanjia.com
    # 代理用来隐藏真实访问中,代理也不允许频繁访问某一个固定网站,所以,代理一定要很多很多
    # 基本使用步骤:

    from urllib import  request, error
    url = "http://www.baidu.com"
    # 使用代理步骤
    # 1. 设置代理地址
    proxy = {'http': '120.194.18.90:81' }
    # 2. 创建ProxyHandler
    proxy_handler = request.ProxyHandler(proxy)
    # 3. 创建Opener
    opener = request.build_opener(proxy_handler)
    # 4. 安装Opener
    request.install_opener(opener)
    # 现在如果访问url,则使用代理服务器
    try:
        rsp = request.urlopen(url)
        html = rsp.read().decode()
        print(html)
    except error.URLError as e:
        print(e)
    except Exception as e:
        print(e)

# cookie & session
    # 由于http协议的无记忆性,人们为了弥补这个缺憾,所采用的一个补充协议
    # cookie是发放给用户(即http浏览器)的一段信息,session是保存在服务器上的对应的另一半信息,用来记录用户信息
    
# cookie和session的区别
    # 存放位置不同
    # cookie不安全
    # session会保存在服务器上一定时间,会过期
    # 单个cookie保存数据不超过4k, 很多浏览器限制一个站点最多保存20个
    
# session的存放位置
    # 存在服务器端
    # 一般情况,session是放在内存中或者数据库中
    # 没有cookie登录,反馈网页为未登录状态
    
# 使用cookie登录
    # 直接把cookie复制下来,然后手动放入请求头:
    headers = {
        "Cookie": "xxxx"
    }
    req = request.Request(url, headers=headers)
    
    # http模块包含一些关于cookie的模块,通过他们我们可以自动使用cookie
        # CookieJar
            # 管理存储cookie,向传出的http请求添加cookie,
            # cookie存储在内存中,CookieJar实例回收后cookie将消失
        # FileCookieJar(filename, delayload=None, policy=None):
            # 使用文件管理cookie
            # filename是保存cookie的文件
        # MozillaCookieJar(filename, delayload=None, policy=None):
            # 创建与mozilla浏览器cookie.txt兼容的FileCookieJar实例
        # LwpCookieJar(filename, delayload=None, policy=None):
            # 创建与libwww-perl标准兼容的Set-Cookie3格式的FileCookieJar实例
        # 他们的关系是: CookieJar-->FileCookieJar-->MozillaCookieJar & LwpCookieJar
       
    # handler是Handler的实例
        # 用来处理复杂请求 
    # 创立handler后,使用opener打开,打开后相应的业务由相应的hanlder处理
    # cookie的保存-FileCookieJar
        cookie.save(ignore_discard=True, ignore_expires=True)
    # cookie的读取:
        cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True)
                
    # 案例:利用cookiejar访问网站

# 自动使用cookie登录,大致流程是
# 打开登录页面后自动通过用户名密码登录
# 自动提取反馈回来的cookie
# 利用提取的cookie登录隐私页面    

from urllib import request, parse
from http import cookiejar

# 创建cookiejar的实例
# cookie = cookiejar.CookieJar()
# 需要保存成文本时创建MozillaCookieJar或FileCookieJar的实例
filename = "cookie.txt"
cookie = cookiejar.MozillaCookieJar(filename)
# cookie的读取:
# cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True)
# 生成 cookie的管理器
cookie_handler = request.HTTPCookieProcessor(cookie)
# 创建http请求管理器
http_handler = request.HTTPHandler()
# 生成https管理器
https_handler = request.HTTPSHandler()
# 创建请求管理器
opener = request.build_opener(http_handler, https_handler, cookie_handler)
def login():
    '''
    负责初次登录
    需要输入用户名密码,用来获取登录cookie凭证
    :return:
    '''
    # 此url需要从登录form的action属性中提取
    url = "http://www.renren.com/PLogin.do"
    # 此键值需要从登录form的两个对应input中提取name属性
    data = {
        "email": "13119144223",
        "password": "123456"
    }
    # 把数据进行编码
    data = parse.urlencode(data)
    # 创建一个请求对象
    req = request.Request(url, data=data.encode())
    # 使用opener发起请求
    rsp = opener.open(req)
    
    # 保存cookie到文件
    # ignor_discard表示即使cookie将要被丢弃也要保存下来
    # ignore_expire表示如果该文件中cookie即使已经过期,保存
    cookie.save(ignore_discard=True, ignore_expires=True)
    
def getHomePage():
    url = "http://www.renren.com/965187997/profile"
    # 如果已经执行了login函数,则opener自动已经包含相应的cookie值
    rsp = opener.open(url)
    html = rsp.read().decode()
   
if __name__ == '__main__':
    login()
    getHomePage()

    # cookie作为一个变量,打印出来, 案例片段:

    print(cookie)
    for item in cookie:
        print(type(item))
        print(item)
        for i in dir(item):
            print(i)


    # cookie的属性
        # name: 名称
        # value: 值
        # domain:可以访问此cookie的域名
        # path: 可以访问此cookie的页面路径
        # expires:过期时间
        # size: 大小
        # Http字段
            
# SSL
    # SSL证书就是指遵守SSL安全套阶层协议的服务器数字证书(SercureSocketLayer)
    # 美国网景公司开发
    # CA(CertifacateAuthority)是数字证书认证中心,是发放,管理,废除数字证书的收信人的第三方机构
    # 遇到不信任的SSL证书,需要单独处理,案例:

# 导入pythopn ssl处理模块
import ssl

# 利用非认证上下文环境替换认证的向下文环境
ssl._create_default_https_context = ssl._create_unverified_context
url = "https://www.12306.cn/mormhweb/"
rsp = request.urlopen(url)
html = rsp.read().decode()

# js加密
    # 有的反爬虫策略采用js对需要传输的数据进行加密处理(通常是取md5值)
    # 经过加密,传输的就是密文,但是
    # 加密函数或者过程一定是在浏览器完成,也就是一定会把代码(js代码)暴露给使用者
    # 通过阅读加密算法,就可以模拟出加密过程,从而达到破解
    # 过程参看案例v19
    # 注意salt,sign的计算
    
# ajax
    # 异步请求
    # 一定会有url,请求方法,可能有数据
    # 一般使用json格式
    # 案例,爬去豆瓣电影, 案例v20
    # 注意请求值
    
#================================Requests==========================
# HTTP for Humans,更简洁更友好
# 继承了urllib的所有特征
# 底层使用的是urllib3
# 开源地址: https://github.com/requests/requests
# 中文文档: http://docs.python#requests.org/zh_CN/latest/index.html   
# 安装: conda install requests
# get请求
    # requests.get(url)
    # requests.request("get", url)
    # 可以带有headers和parmas参数

import requests

url = "http://www.baidu.com"
# 两种请求方式
# 使用get请求
rsp = requests.get(url)
print(rsp.text)

# 使用request请求
rsp = requests.request("get", url, params=kw, headers=headers)
print(rsp.text)

# get返回内容
print(rsp.text)
print(rsp.content)
print(rsp.url)
print(rsp.encoding)
print(rsp.status_code) # 请求返回码

    # post

rsp = requests.post(baseurl, data=data,  headers=headers)

    # date, headers要求dict类型,不需要编码成byte流
   # proxy
   # 

proxies = {
"http":"address of proxy",
"https": "address of proxy"
}
rsp = requests.request("get", "http:xxxxxx", proxies=proxies)

# 代理有可能报错,如果使用人数多,考虑安全问题,可能会被强行关闭
# 用户验证
    # 代理验证

#可能需要使用HTTP basic Auth, 可以这样
# 格式为  用户名:密码@代理地址:端口地址
proxy = { "http": "china:123456@192.168.1.123:4444"}
rsp = requests.get("http://baidu.com", proxies=proxy)

# web客户端验证
    # 如果遇到web客户端验证,需要添加auth=(用户名,密码)

autu=("test1", "123456")#授权信息
rsp = requests.get("http://www.baidu.com", auth=auth)

# cookie

# requests可以自动处理cookie信息
rsp = requests.get("http://xxxxxxxxxxx")
# 如果对方服务器给传送过来cookie信息,则可以通过反馈的cookie属性得到
# 返回一个cookiejar实例
cookiejar = rsp.cookies   
#可以讲cookiejar转换成字典
cookiedict = requests.utils.dict_from_cookiejar(cookiejar)         

# session
    # 跟服务器端session不是一个东东
    # 模拟一次会话,从客户端浏览器链接服务器开始,到客户端浏览器断开
    # 能让我们跨请求时保持某些参数,比如在同一个session实例发出的 所有请求之间保持cookie

# 创建session对象,可以保持cookie值
ss = requests.session()
headers = {"User-Agent":"xxxxxxxxxxxxxxxxxx"}
data = {"name":"xxxxxxxxxxx"}
# 此时,由创建的session管理请求,负责发出请求,
ss.post("http://www.baidu.com", data=data, headers=headers)
rsp = ss.get("xxxxxxxxxxxx")

# https请求验证ssl证书
    # 参数verify负责表示是否需要验证ssL证书,默认是True
    # 如果不需要验证ssl证书,则设置成False表示关闭
    # 如果用verify=True访问12306,会报错,因为他证书有问题 

rsp = requests.get("https://www.baidu.com", verify=False)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值