精通python网络爬虫笔记一

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011529752/article/details/78296866

1. urllib使用

1.1 一个简单的例子

入门例子html源码

解析百度的

import urllib.request

file = urllib.request.urlopen("http://www.baidu.com")

#data = file.read()     
#dataline = file.readline()
datalines = file.readlines()

#print(data)
#print(dataline)
print(datalines)
  • read、readline和readlines会设置当前文件指针或者刷新流,直接一起用会有问题。比如先用read再用readlines就会得到空的列表
  • urllib文档地址
  • urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)函数文档

1.2 保存在文件中并查看部分信息

# -*- coding: utf-8 -*-
from urllib import request

urladd = "http://www.baidu.com"
file = request.urlopen(urladd)

data = file.read()
print(data)

htmlfile = open("baidu.html",'wb')
htmlfile.write(data)
htmlfile.close()

#直接写入html文件
htmlfile2 = request.urlretrieve(urladd,"baidu2.html") #retrieve 是取回的意思
request.urlcleanup()

print(file.info())    #
print(file.getcode()) #状态码
print(file.geturl())

## 1.3 对中文字符的处理

request 下面有一个quote函数,用来对中文等特殊字符进行编码

用法是:

urllib.parse.quote(string, safe=’/’, encoding=None, errors=None)文档地址

# -*- coding: utf-8 -*-
from urllib import request

urladd = u"https://www.baidu.com/s?ie=UTF-8&wd=urllib 手册"
urladd = request.quote(urladd,safe='/:=?') #不加这句会报错
file = request.urlopen(urladd)

data = file.read()
print(data)

1.4 User-Agent 和 模拟Header

在本机的浏览器按f12,在network下点击第一个url,在最下面有一行RequestHeader:

本机在本系统本网络环境中的user-agent

user-agent:

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36

User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。

–from 百度百科

在某些网页设置了反爬虫的机制,没有user-agent的信息会返回403错误,当然有的时候也可以用来伪造user-agnet,header信息除了user-agnet之外还有其他的信息,比如Referer等

两种方法

  1. 使用build_opener:

    
    # -*- coding: utf-8 -*-
    
    from urllib import request
    
    urladd = u"https://www.baidu.com/"
    header = ("user-agent","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36") #添加header信息
    opener = request.build_opener()
    opener.addheaders = [header]
    file = opener.open(urladd)
    
    #file = request.urlopen(urladd)
    
    
    data = file.read()
    print(data)

  2. 使用Request:

    
    # -*- coding: utf-8 -*-
    
    from urllib import request
    
    urladd = u"https://www.baidu.com/"
    key = "user-agent"
    value = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"
    
    req = request.Request(urladd)
    req.add_header(key,value)
    
    print(req)
    
    file = request.urlopen(req)
    
    #file = request.urlopen(urladd)
    
    
    data = file.read()
    print(data)

    其实在request.urlopen()的参数中传入字符串会自动生成Request对象

1.5 超时设置

就是request.urlopen()中的timeout参数,单位为秒

# -*- coding: utf-8 -*-
from urllib import request

urladd = u"https://www.baidu.com/"
key = "user-agent"
value = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"

for i in range(1,10):
    try:
        req = request.Request(urladd)
        req.add_header(key,value)

        print(req)

        file = request.urlopen(req,timeout=0.5)
        #file = request.urlopen(urladd)

        data = file.read()
        print(data)
    except Exception as e:
        print(str(e))

1.6 HTTP请求

1.6.1 使用get请求访问百度并搜索一个关键词

# -*- coding: utf-8 -*-
from urllib import request

urladd = "https://www.baidu.com/s?&wd=" + request.quote("我的老家") #此处需要编码
key = "user-agent"
value = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"

req = request.Request(urladd)   #构造url请求对象
req.add_header(key,value)       #加入头

file = request.urlopen(req,timeout=1)   #设置时间
#file = request.urlopen(urladd)

data = file.read()
print(data)

file = open("baidu_wd.html",'wb')
file.write(data)
file.close()
  1. url地址请求的格式是”http://网址?字段名1=字段内容1&字段名2=字段内容2”

1.6.2 POST提交表单

要使用parse模块,parse模块是用来解析的

# -*- coding: utf-8 -*-
from urllib import request
from urllib import parse

urladd = "http://www.iqianyue.com/mypost/"
key = "user-agent"
value = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"

postdata = parse.urlencode({
    "name":"[email protected]",
    "pass":"aA123456"
}).encode('utf-8')  #这里一定要调用encode方法来编码

req = request.Request(urladd,data=postdata)
req.add_header(key,value)
#req.data = postdata    #可以用这个来指定成员
file = request.urlopen(req,timeout=10)
#file = request.urlopen(urladd)

data = file.read()
print(data)

file = open("post.html",'wb')
file.write(data)
file.close()
  1. 传递的表单就是在html代码的form条目下,每项的名称就是name=后面的字段,每项的有值,需要用字典包起来。再编码,这是Request对象的一部分

1.6.3 代理服务器设置

# -*- coding: utf-8 -*-
from urllib import request
from urllib import parse

def use_proxy(proxy_addr,urladdr):
    proxy = request.ProxyHandler({'http':proxy_addr})   #设置代理的IP和端口
    opener = request.build_opener(proxy,request.HTTPHandler)
    request.install_opener(opener)      #安装全局的opener对象
    key = "user-agent"
    value = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"

    postdata = parse.urlencode({
        "name": "[email protected]",
        "pass": "aA1234567"
    }).encode('utf-8')

    req = request.Request(urladd, data=postdata)
    req.add_header(key, value)
    # req.data = postdata
    file = request.urlopen(req, timeout=10)
    # file = request.urlopen(urladd)

    data = file.read()
    return  data

urladd = "http://www.iqianyue.com/mypost/"
proxy_addr = "118.114.77.47:8080"

data = use_proxy(proxy_addr=proxy_addr,urladdr=urladd)

file = open("post_proxy.html",'wb')
file.write(data)
file.close()
  1. 安装全局的opener需要传入句柄handler对象,上面的代码中proxy是代理的句柄,request.HTTPHandler也是一个句柄,据此构造了一个opener。install_opener安装全局的opener,这样就可以使用urlopen来打开网页了。
  2. 如果不调用install_opener(),则需要调用opener.open()来打开
  3. 代理的ip和端口可以在http://www.xicidaili.com/获取

1.6.4 打印日志

构造HTTPHandler或者HTTPSHandler对象的时候,设置debuglevel=1,即可,1.6.3的代码只需要修改

    opener = request.build_opener(proxy,request.HTTPHandler)

    opener = request.build_opener(proxy,request.HTTPHandler(debuglevel=1))

即可

这样日志就会打印在控制台中

1.6.5 异常处理

用到error模块,文档地址

主要就是用try except 来捕获错误

# -*- coding: utf-8 -*-
from urllib import request
from urllib import error

try:
    request.urlopen("http://blog.csdn.com")
except error.HTTPError as e:
    print(e.code)
    print(e.reason)
except error.URLError as e:
    print(e.reason)

HTTPError 是 URLError的子类,有code成员,所以要写成上面的形式。

http的常用错误码:

代码 英文 中文含义
200 OK 一切正常
301 Moved Permanently 永久重定向
302 Found 临时重定向到资源
304 Not Modified 请求的资源没有更新
400 Bad Request 非法请求
401 Unauthorized 请求未经授权
403 Forbidden 禁止访问
404 Not Found 没有找到对应页面
500 Internal Server Error 服务器内部出现错误
501 Not Implement 服务器不支持当前请求

1.7 总结

1.7.1 URL和域名

超文本传输协议统一资源定位符(url)将从因特网获取信息的四个基本元素包括在一个简单的地址中:

  1. 传送协议; 2. 服务器; 3. 端口号; 4. 路径。

典型的统一资源定位符看上去是这样的:

https://www.baidu.com/s?rsv_bp=0&rsv_sug2=0&ie=utf-8&word=url%E5%9C%B0%E5%9D%80%E6%A0%BC%E5%BC%8F&tn=99455684_hao_pg

其中:

  1. https,是协议;
  2. www.baidu.com,是服务器;
  3. 80,是服务器上的网络端口号(这里默认不填);
  4. /s,是路径;
  5. ?rsv_bp=0&rsv_sug2=0&ie=utf8&word=url%E5%9C%B0%E5%9D%80%E6%A0%BC%E5%BC%8F&tn=99455684_hao_pg,是询问。

www 是万维网的服务器,是网络名。baidu.com是在网络服务器上注册的主机名,默认端口是80。不加www是一级域名,加了就是二级域名,www只是声明提供的是web服务。

1.7.2 urllib及常用的函数总结

urllib由四个子模块组成

  • request 负责打开和读取url
  • error 负责获取request的错误
  • parse 负责解析url
  • robotparse 负责解析robot.txt文件,即爬虫协议

低端常用的是前三个模块,最重要的是第一个。

  1. request模块的常用函数和常用用法

    • urlopen(url , timeout) ,使用全局的opener,根据url对象打开一个网页,返回一个响应对象,调用响应对象的read,readline或readlines函数就可以获取内容。
    • urlretrieve(url , path) ,直接将url保存在本地路径中
    • build_opener(handler,…) , 使用句柄构造opener对象, 句柄可以是代理设置的句柄,如ProxyHandler的返回对象,HTTPHandler对象等,可以并排,HTTPHandler(debuglevel=1)可以打印日志。
    • opener.open() ,和urlopen()功能一样,只不过是设置不同。
    • opener_install(opener) , 把opener设置为全局的opener,这样就可以直接调用urlopen()来使用opener的设置了。
    • Request(url,data=postdata),构造url请求对象,可以调用add_header(key,value)来添加http头,data参数可以是post的表单对象
    • ProxyHandler({‘http’:proxy_addr}) 设置代理地址,返回代理句柄
  2. error的使用

    • URLError
    • HTTPError
  3. parse的使用

    • quote(str)

    • unquote(str) 编码与反编码

    • urlencode( ) 构造表单数据

       postdata = parse.urlencode({
           "name": "[email protected]",
           "pass": "aA1234567"
       }).encode('utf-8')
      
       req = request.Request(urladd, data=postdata)

猜你喜欢

转载自blog.csdn.net/u011529752/article/details/78296866
今日推荐