zoukankan      html  css  js  c++  java
  • 初识爬虫

    原文

    爬虫的本质是向一个网站或URL发送请求,获取资源后分析并提取有用数据的应用程序。它可以用来获取文本数据,也可以用来下载图片或音乐,还可以用来抢票。

    爬虫的工作程序(三步走):

    1. 请求发送:确定需要爬取数据的目标url以及发送请求(request)时所需要携带的数据和各种HTTP头部信息。python3最常用的库 urllib和requests
    2. 数据解析:对返回的数据进行解析,提取我们所需要的信息。常用的库有:html.parser, beautifulsoup, lxml
    3. 数据存储:对第2步提取的数据,存入数据库或者写入磁盘文件(如csv文件)或缓存

    例子:

    简单的使用urllib库爬csdn首页的html代码:

    #-*- coding: UTF-8 -*-
    #使用 urllib库开发一个最简单的爬虫 爬csdn首页的html代码
    
    from urllib import request
    
    if __name__ == '__main__':
        response = request.urlopen("https://www.csdn.net/")
        html = response.read()
        print(html)

    运行上面的代码会爬出csdn首页的源代码。但是遇到中文字符时都是乱码。是因为python在解析网页时默认使用Unicode去解析,而大多数网站是utf-8格式的。我们需要使用html.decode('utf-8')对返回的数据进行解码。

    #-*- coding: UTF-8 -*-
    #使用 urllib库开发一个最简单的爬虫 爬csdn首页的html代码
    
    from urllib import request
    
    if __name__ == '__main__':
        response = request.urlopen("https://www.csdn.net/")
        html = response.read()
        html = html.decode('utf-8')
        print(html)

    如果不知道目标网页的编码格式,我们可以通过第三方库chardet自动获取目标网页的编码。常见的网页编码有 GB2312, GBK, utf-8 和unicode.
    代码样例:

    #-*- coding: UTF-8 -*-
    #使用 urllib库开发一个最简单的爬虫 爬csdn首页的html代码
    
    from urllib import request
    import  chardet
    
    if __name__ == '__main__':
        response = request.urlopen("https://www.csdn.net/")
        html = response.read()
        chardet = chardet.detect(html) #返回字典
        print(chardet['encoding'])
        html = html.decode(chardet['encoding'])
        print(html)

    python3 的 urllib库介绍:

    urllib库主要包含四个模块:

    • urllib.request 基本的http请求模块。可以模拟浏览器向目标服务器发送请求
    • urllib.error 异常处理模块。可以捕获异常
    • urllib.parse 工具模块,提供url 处理方法。比如对URL进行编码和解码
    • urllib.robopaser 用来判断哪些网站可以爬,哪些网站不可以爬

    在刚才的例子中,我们用urlopen方法打开了一个实际的链接url。但在实际开发爬虫过程中,我们一般先构建request对象,再通过urlopen方法发送请求。这是因为构建的request url 可以包含GET参数或POST 数据以及头部信息。这些信息是普通的url 不能包含的。

    #-*- coding: UTF-8 -*-
    #使用 urllib库开发一个最简单的爬虫 爬csdn首页的html代码
    #使用request_url
    
    from urllib import request
    import  chardet
    
    if __name__ == '__main__':
        request_url = request.Request("https://www.csdn.net")
        response = request.urlopen(request_url)
        html = response.read()
        chardet = chardet.detect(html)
        print(chardet['encoding'])
        html = html.decode(chardet['encoding'])
        print(html)

    使用urllib发送带参数的get请求:

    例子:向csdn网站搜索页面模拟发送带参数get请求。 请求参数是 q=大江狗.返回数据是搜索结果。

    1.  使用urllib.urlencode方法对需要发送的get参数进行url编码
    2. 对url 进行拼接
    3. 添加请求头信息 (添加请求头的原因是很多网站服务器有反爬机制,一般不带请求头的访问都会被认为是爬虫,从而禁止它们的访问

    csdn搜索页面的链接和搜索参数:

    代码:

    #-*- coding: UTF-8 -*-
    #使用 urllib库开发一个最简单的爬虫 爬csdn首页的html代码
    
    from urllib import request
    import urllib.parse
    import  chardet
    
    if __name__ == '__main__':
        url = "https://so.csdn.net/so/search/s.do"
        params = {'q':'大江狗',}
        header = {
            "User-Agent": " Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",
        }
        #使用parse方法对参数进行URL编码
        encoded_params = urllib.parse.urlencode(params)
        #拼接后的request地址
        request_url = request.Request(url+"?"+encoded_params,headers=header)
        response = request.urlopen(request_url)
        html = response.read()
        chardet = chardet.detect(html)
        print(chardet['encoding'])
        html = html.decode(chardet['encoding'])
        print(html)

    使用urlib发送post数据:

    模拟向一个网站提交表单数据。可以通过构建request对象并加入POST数据,然后使用urlopen方法发送请求。与get请求不同的是url无需要拼接。需要发送的参数也不会出现在url里

    #-*- coding: UTF-8 -*-
    #使用 urllib库开发一个最简单的爬虫 爬csdn首页的html代码
    
    from urllib import request
    import urllib.parse
    import  chardet
    
    if __name__ == '__main__':
        url = "some_url"
        post_data = {'name':'大江狗',}
        header = {
            "User-Agent": " Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",
        }
        #使用parse方法对参数进行URL编码
        encoded_data = urllib.parse.urlencode(post_data).encode('utf-8')
        #使用urllib发送POST数据无需拼接URL
        request_url = request.Request(url,headers=header,data=encoded_data)
        response = request.urlopen(request_url)
        html = response.read()
        chardet = chardet.detect(html)
        print(chardet['encoding'])
        html = html.decode(chardet['encoding'])
        print(html)

    爬取有道翻译上的英文翻译的例子:(在debug的network中查看真正的url)

     

     如果请求方式是POST,我们一定还有了解POST什么数据,服务器才会返回正确的响应:network的 header 可以找到:词,salt和sign.我们在请求里必须把这些data加进去,有道才会返回反应结果。

    #-*- coding: UTF-8 -*-
    #使用 urllib库开发一个最简单的爬虫 爬csdn首页的html代码
    
    from urllib import request
    from urllib import parse
    import time
    import random
    import hashlib
    import json
    import  chardet
    
    '''使用urlopen(request_url,data)发送参数'''
    
    if __name__ == '__main__':
        url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"
        header = {
                     'Accept': 'application / json, text / javascript, * / *; q = 0.01',
        'Accept - Encoding': 'gzip, deflate',
        'Accept - Language': 'zh - CN, zh;q = 0.9',
        'Connection': 'keep - alive',
        'Content - Length': 251,
        'Content - Type': 'application / x - www - form - urlencoded;charset = UTF - 8',
        'Host': 'fanyi.youdao.com',
        'Origin': 'http: // fanyi.youdao.com',
        'Referer': 'http: // fanyi.youdao.com /',
        'User - Agent': 'Mozilla / 5.0(Windows NT 10.0;WOW64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 73.0.3683.86 Safari / 537.36',
        'X - Requested - With': 'XMLHttpRequest',
        }
        i = input("Translation for: ")
        client = "fanyideskweb"
        t = str(int(time.time()*1000))
        salt = t+ str(random.randint(1,10))
        c ='n%A-rKaT5fb[Gy?;N5@Tj'
        md5 = hashlib.md5()
        md5.update(client.encode('utf-8'))
        md5.update(i.encode('utf-8'))
        md5.update(salt.encode('utf-8'))
        md5.update(c.encode('utf-8'))
    
        sign = md5.hexdigest()
        print(salt)
        print(t)
        print(sign)
        data = {
            'i': i,
            'from': 'AUTO',
            'to': 'AUTO',
            'smartresult': 'dict',
            'client':client,
            'salt': salt,
            'sign': sign,
            'ts':   t,
             'bv': '140f03b6cc43b5b1fabe089d78dc366f',
            'doctype': 'json',
            'version': '2.1',
            'keyfrom':'fanyi.web',
            'action':'FY_BY_REALTlME',
        }
    
        #使用parse方法对参数进行URL编码
        data = parse.urlencode(data).encode('utf-8')
        #使用urllib发送POST数据无需拼接URL
        request_url = request.Request(url,data=data,headers=header)
        response = request.urlopen(request_url)
        print(response.getcode()) #200 表示成功
        json_result = json.load(response)
        print(json_result)
        translation_result = json_result['translateResult'][0][0]['tgt']
        print("翻译的结果是:%s" % translation_result)

    '''
    如何破解有道翻译:
    1. 找到相应的 js 文件
    2. 格式化 js 文件: http://tool.chinaz.com/Tools/jsformat.aspx
    3. 找到关键字 salt (加密盐),然后实验和提取 sign参数
    4. 有道翻译的链接是去掉_o。 参考:https://www.jianshu.com/p/2ae887299080
    '''

     异常处理:

     我们必须学会如何捕获那些异常和处理那些异常。urllib.error的模块包括两种主要错误:URLError(坏链接)和 HTTPError. (没有相应的权限).

     import  urllib.error
        try:
            urllib.request.urlopen('htt://www.baidu.com')
        except urllib.error.URLError as e:
            print(e.reason)
        
        try:
            urllib.request.urlopen('http://www.baidu.com/admin')
        except urllib.error.HTTPError as e1:
            print(e1.reason)
            print(e1.code)

    显示本机ip的爬虫例子:(爬 whatismyip.com 站点)

    # -*- coding: UTF-8 -*-
    from urllib import request
    import re
    
    if __name__ == "__main__":
        # 访问网址获取IP
        url = 'https://www.whatismyip.com/ip-address-lookup/'
    
        header = {
            "User-Agent": " Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",
        }
    
        # 构建request对象
       request_url = request.Request(url, headers=header)
    
        # 发送请求获取返回数据
       response = request.urlopen(request_url)
        
        # 读取相应信息并解码,并利用正则提取IP
        html = response.read().decode("utf-8")
        pattern = re.compile(r'(?:[0-9]{1,3}.){3}[0-9]{1,3}')
        ip_list = re.findall(pattern, html)
    
        print(ip_list[0])
  • 相关阅读:
    HDU1754 I hate it(线段树 单点修改)
    计算几何题目(转)
    大根堆(模板)
    CodeForces
    CodeForces
    乘法逆元(模数为质数,费马小定理)
    20151225jquery学习笔记---选项卡UI
    20151224jquery学习笔记---cookie插件
    20151223jquery学习笔记--Ajax表单提交
    20151222jquery学习笔记--验证注册表单
  • 原文地址:https://www.cnblogs.com/ahMay/p/11984073.html
Copyright © 2011-2022 走看看