python爬虫(Spider)之(使用urlopen、response简介、chardet检测编码、urllib之requests、error、parse|爬虫实现百度翻译)

准备工作

-参考资料

         -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

1、爬虫简介

-爬虫定义:网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常地称为网页追逐着),是一种按照一定规则,自动地抓取万维网信息地程序或者脚本。另外以西为不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

-两大特征

        -能按作者要求下载数据或者内容

        -能自动在网络上流窜

-三大步骤

        -下载信息

        -提取正确的信息

        -根据一定规则自动跳到另外的网页上执行上两部内容

-爬虫分类

        -通用爬虫

        -专用爬虫(聚焦爬虫)

-Python网络包简介

        -Python2.x:urllib,urllib2,urllib3,httplib,httplib2,requests

        -Python3.x:urllib,urllib3,httplib2,requests

        -python2:urllib和urllib2配合使用,或者requests

        -Python3:urllib,requests

2、urllib

-包含模块

        -urllib.requests:打开和读取urls

        -urllib.error:包含urllib.request产生的常见的错误,使用try捕捉

        -urllib.parse:包含解析url的方法

        -urllib.robotparse:解析robots.txt文件

from urllib import request

#使用urllib.request请求一个网页内容,并把内容打印出来

if __name__ == '__main__':
    url = "http://landing.zhaopin.com/register?utm_source=360PC&utm_medium=CPC&utm_term=6890000&utm_content=qg&utm_campaign=sszdpp&utm_provider=partner&sid=121122526&site=u243985234.c4257288517.g2346222611.k17815376351.pq"
    #打开相应url并把相应页面作为返回
    rsp = request.urlopen(url)

    #把返回结果读取出来
    #读取出来内容类型为bytes
    html = rsp.read()
    print(type(html))

    #如果想把bytes内容转换成字符串,需要解码
    html = html.decode()   #括号可填参数,例如“utf-8”
    print(html)
  

-网页编码问题解决

        -chardet:可以自动检测页面文件的编码格式,但是可能有误

        -需要安装,conda install chardet

'''
利用request下载页面,自动检测页面编码
'''
import urllib.request,chardet
if __name__ == '__main__':
    url = "https://mil.news.sina.com.cn/"
    rsp = urllib.request.urlopen(url)
    html = rsp.read()

    #利用 chardet自动检测
    cs = chardet.detect(html)
    print(type(cs))
    print(cs)

    html= html.decode(cs.get("encoding","utf-8"))
    print(html)

错误: rsp = urllib.request.urlopen(url)
           AttributeError: module 'urllib' has no attribute 'request'

解决:将import urllib 改为 import urllib.request,有时候pycharm不会导入子模块

-urlopen的返回对象

         -geturl:返回请求对象的url

         -info:请求反馈对象的meta信息

         -getcode:返回的http code

import urllib.request
if __name__ == '__main__':
    url = "https://mil.news.sina.com.cn/"
    rsp = urllib.request.urlopen(url)

    print(type(rsp))
    print(rsp)

    print("URL: {0}".format(rsp.geturl()))
    print("Info: {0}".format(rsp.info()))
    print("Code: {0}".format(rsp.getcode()))

    html = rsp.read()

-request.date的使用

        -访问网络的两种方法

                -get:利用参数给服务器传递消息;参数为dict,然后用parse编码

from urllib import request,parse

'''
掌握对url进行参数编码的方法,需要使用paarse模块
'''
if __name__ == '__main__':
    url = "https://www.baidu.com/s?"
    wd = input("Input your keyword:")

    qs = {
        "wd":wd
    }

    #转换url编码
    qs = parse.urlencode(qs)
    print(qs)

    fullurl = url + qs
    print(fullurl)

    #如果直接用可读的带参数的url,是不能直接访问的
    #fullurl = "https://www.baidu.com/s?wd=大熊猫"

    rsp = request.urlopen(fullurl)
    html = rsp.read()

    #使用get取值保证不会出错
    html = html.decode()

    print(html)

运行:
Input your keyword:哈哈
wd=%E5%93%88%E5%93%88
https://www.baidu.com/s?wd=%E5%93%88%E5%93%88
<!DOCTYPE html>
<!--STATUS OK-->

                -post:一般向服务器传递参数使用;post是把信息自动加密处理;我们如果想使用post信息,需要用到data参数

                            使用post意味着http的请求头可能需要更改:

                                   -Content-Type:application/x-www.form-urlencode

                                   -Content-length:数据长度

                                   -简而言之,一旦更改请求方法,请注意其请求头部信息相适应

                           urllib.parse.urlencode可以将字符串自动转换成上面的

'''
利用parse模块模拟post请求,分析百度词典
分析步骤:
1、打开审查元素
2、尝试输入单词girl,发现每敲一个字母后都有请求
3、请求地址是 http://fanyi.baidu.com/sug
4、利用NetWork-All-Headers-查看-发现FormData的值是kw:girl
5、检查返回内容格式,发现返回的是json格式内容==>需要用到json包
'''
from urllib import request,parse
#负责处理json格式模块
import json

'''
大概流程:
1、利用data构造内容,然后urlopen打开
2、返回一个json格式的结果
3、结果就应该是girl的释义
'''

baseurl = "https://fanyi.baidu.com/sug"
#存放用来模拟form的数据一定是dict格式
data = {
    #girl是编译输入的英文内容,应该是由用户输入,此处使用硬编码
    'kw':"girl"
}

#需要使用parse模块对data进行编码
data = parse.urlencode(data).encode("utf-8")

print(type(data))
#我们需要构造一个请求头,请求头部应该至少包含传入的数据的长度
#request要求传入的请求头是一个dict格式

headers = {
    #因为使用post,至少应该包含content-length 字段
    'Content-Length':len(data)
}

#有了headers-data-url 就可以尝试发出请求了
rsp = request.urlopen(baseurl,data=data)

#encode编成字节流
json_data = rsp.read().decode('utf-8')
print(type(json_data))
print(json_data)

#把json字符串转化成字典
json_data = json.loads(json_data)
print(type(json_data))
print(json_data)

#print(json_data['data'])
for item in json_data["data"]:
    print(item['k'],'--',item['v'])
运行:
<class 'bytes'>
<class 'str'>
{"errno":0,"data":[{"k":"girl","v":"n. \u5973\u5b69; \u59d1\u5a18\uff0c\u672a\u5a5a\u5973\u5b50; \u5973\u804c\u5458\uff0c\u5973\u6f14\u5458; \uff08\u7537\u4eba\u7684\uff09\u5973\u670b\u53cb;"},{"k":"girls","v":"n. \u5973\u5b69; \u5973\u513f( girl\u7684\u540d\u8bcd\u590d\u6570 ); \u5973\u5de5; \uff08\u7537\u4eba\u7684\uff09\u5973\u670b\u53cb;"},{"k":"girlfriend","v":"n. \u5973\u670b\u53cb; \u5973\u6027\u670b\u53cb;"},{"k":"girl friend","v":"n. \u5973\u670b\u53cb\uff0c\uff08\u7537\u4eba\u7684\uff09\u60c5\u4eba; \u5bf9\u8c61;"},{"k":"Girls' Generation","v":" \u5c11\u5973\u65f6\u4ee3\uff08\u97e9\u56fdSM\u5a31\u4e50\u6709\u9650\u516c\u53f8\u4e8e2007\u5e74\u63a8\u51fa\u7684\u4e5d\u540d\u5973\u5b50\u5c11\u5973\u7ec4\u5408\uff09;"}]}
<class 'dict'>
{'errno': 0, 'data': [{'k': 'girl', 'v': 'n. 女孩; 姑娘,未婚女子; 女职员,女演员; (男人的)女朋友;'}, {'k': 'girls', 'v': 'n. 女孩; 女儿( girl的名词复数 ); 女工; (男人的)女朋友;'}, {'k': 'girlfriend', 'v': 'n. 女朋友; 女性朋友;'}, {'k': 'girl friend', 'v': 'n. 女朋友,(男人的)情人; 对象;'}, {'k': "Girls' Generation", 'v': ' 少女时代(韩国SM娱乐有限公司于2007年推出的九名女子少女组合);'}]}
girl -- n. 女孩; 姑娘,未婚女子; 女职员,女演员; (男人的)女朋友;
girls -- n. 女孩; 女儿( girl的名词复数 ); 女工; (男人的)女朋友;
girlfriend -- n. 女朋友; 女性朋友;
girl friend -- n. 女朋友,(男人的)情人; 对象;
Girls' Generation --  少女时代(韩国SM娱乐有限公司于2007年推出的九名女子少女组合);

                -为了更多的设置请求信息,单纯地通过urlopen函数已经不太好用了,需要用request.Request类,模拟一个请求的实体

                request可以无限制地设置header,往里面塞各种内容

-urllib.error

      -URLError产生的原因:-没网

                                            -服务器连接失败

                                            -找不到指定服务器

                                            -osEroor的子类

      -HTTPError,是URLError的一个子类

'''
URLerror的使用
'''
from urllib import request,error

if __name__ == '__main__':
    url = "http://www.baidubjkvkl.com"
    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以上的则引发HTTPEroor

                    -URLError对应的一般是网络出现问题,包括url问题

                    -关系区别:OSError-URLError-HTTPError

 

  


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值