• 爬虫--urllib,requests模块


    一、urllib模块-(了解即可,用的不多)

    二、requests模块

    2.0、requests模块--response的方法

    2.1、基于requests模块发起get请求

    2.2、基于requests模块发起get请求(带参数)

    2-3、基于requests模块发起get请求(自定义请求头)

    2-4、基于requests模块发起post请求(请求头content-type=application/x-www-form-urlencoded

    2-4(1)、基于requests模块发起post请求(请求头content-type=multipart/form-data)上传文件

    2-4(2)、基于requests模块发起post请求(请求头content-type=application/json

    2-5、基于requests模块发起ajax(get)请求-略

    2-6、基于requests模块发起ajax(post)请求-略 

    2-7、requests模块综合练习

    三、requests模块高级(cookie, 代理)

    3.1、cookie

    3.2、cookie操作:获取某用户的个人主页(先登录再获取)

    3.3、代理(正向代理)

    3.4、代理操作:更换IP然后向百度搜索的IP关键字发请求,看IP所在地

    四、验证码处理-打码平台

    =============================================================================================

    robots.txt协议
    是网站规定的哪些数据可以爬取,哪些不能爬取,不是强制遵守的
    例如:淘宝的www.taobao.com/robots.txt
     

    一、urllib模块-(了解即可,用的不多)

    urllib、requests模块,主要使用requests模块

    数据爬取步骤:
    1、指定url
    2、发请求
    3、获取页面数据
    4、持久化存储


    需求1:爬取搜狗首页---(无参数GET请求)
    import urllib.request
    url = 'https://www.baidu.com/'   # 请求url
    response = urllib.request.urlopen(url=url)
    page_text = response.read()   # bytes类型的页面数据
    with open('./sougou.html','wb') as fp:
      fp.wirte(page_text)
    print('写入数据成功')


    需求2;爬取指定词条对应的数据---(有参数GET请求,参数为中文)
    import urllib.request
    import urllib.parse
    # url = 'https://www.baidu.com/s?wd=哈哈'
    # 请求url中存在非ASCII编码的字符数据,会出错,要转码再拼接
    word = urllib.parse.quote("哈哈")
    url = 'https://www.baidu.com/s?wd=' + word
    response = urllib.request.urlopen(url=url)
    page_text = response.read() # bytes类型的页面数据
    with open('./sougou.html','wb') as fp:
      fp.wirte(page_text)
    print('写入数据成功')


    需求3:反爬机制:网站检查请求的UA---(GET请求,指定请求头)
    User-Agent(UA):浏览器身份标识
    反反爬机制:UA伪装,请求头的"User-Agent"

    UA伪装:
    import urllib.request
    url = "https://www.baidu.com/"
    headers = {
    "User-Agent": "Mozilla/5.0"
    }
    request = urllib.request.Request(url=url,headers=headers)
    response = urllib.request.urlopen(request)
    page_text = response.read()
    with open('./sougou.html','wb') as fp:
      fp.wirte(page_text)
    print('写入数据成功')

    post请求携带参数进行处理
    1.将post请求参数封装到字典
    2.使用parse模块中的urlencode进行编码处理(返回值类型为str)
    3.将第二步获取的编码结果转换为bytes类型
    4.发起post请求:urlopen函数的data参数就是经过处理的post请求携带请求数据

    需求4:爬取百度翻译的翻译结果(POST请求)
    import urllib.request
    import urllib.parse
    url = 'https://fanyi.baidu.com/sug'
    data = {
    'kw':'西瓜'
    }
    data = urllib.parse.urlencode(data)
    data = data.encode()
    response = urllib.request.urlopen(url=url, data=data)
    response.read()

    需求5:urllib高级操作,一般不用,太繁琐
    参考http://www.xiaobaibook.com/details/51/
    1、代理
    2、cookie

      

    二、requests模块

    requests模块功能强大,使用方便,掌握了requests就掌握了爬虫的半壁江山
    安装:pip install requests
    五个项目学习和巩固requests模块:
    - get
    - post
    - ajax(get)
    - ajax(post)
    - 综合

    2.0、requests模块--response的方法

    ------------------------------------
    response.text : 字符串形式的页面数据
    response.content : 二进制形式的页面数据
    response.status_code : 响应状态码
    response.headers : 响应头信息
    response.url : 本次请求的url
    ------------------------------------

    2.1、基于requests模块发起get请求

    例如:爬取百度首页的页面数据
    import requests
    url = "https://www.baidu.com/"
    # 返回请求成功的响应对象
    response = requests.get(url=url)
    # 获取响应对象中的数据
    page_text = response.text
    with open('./sougou.html','wb',encoding="utf8") as fp:
      fp.wirte(page_text)
    print('写入数据成功')

    2.2、基于requests模块发起get请求(带参数)

    例如:爬取百度搜索词条的搜索结果
    方法一:参数拼接在url里
    import requests
    url = 'https://www.baidu.com/s?wd=哈哈'
    response = requests.get(url=url)
    方法二:参数放在get方法里
    import requests
    url = 'https://www.baidu.com/s'
    params = {
    "wd":"哈哈"
    }
    response = requests.get(url=url, params=params)

    2-3、基于requests模块发起get请求(自定义请求头)

    import requests
    url = "https://www.baidu.com/"
    headers = {
    "User-Agent": "Mozilla/5.0"
    }
    response = requests.get(url=url, headers=headers)

    2-4、基于requests模块发起post请求(请求头content-type=application/x-www-form-urlencoded

    例如:登录豆瓣网,获取登录成功后的页面数据
    import requests
    url = "https://movie.douban.com/login/"
    data =
    "source":"movie",
    "redir":"https://movie.douban.com/",
    "form_email":15203949239,
    "form_password":hh12345,
    "login":"登录",
    }
    headers = {
    "User-Agent": "Mozilla/5.0"
    }
    requests.post(url=url,data=data,headers=headers)

    2-4(1)、基于requests模块发起post请求(请求头content-type=multipart/form-data)上传文件

    import requests,json
     
    url_mul = 'http://httpbin.org/post'
    files = {'file':open('E://report.txt','rb')}
    r = requests.post(url_mul,files=files)
    print(r)
    print(r.text)
    print(r.content)

    2-4(2)、基于requests模块发起post请求(请求头content-type=application/json

    def fzjg():
        '''
        分支机构
        :return:
        '''
        api = '/api/v1.0/company/basic/query/fzjg'
        url = 'http://xfrm.safe.gov.cn/api/v1.0/company/basic/query/fzjg'
        data = {
            "pageNum": '1',
            "pageSize": '10',
            "qyxxId": globals()['ID'],
        }
        headers = {
            "Content-Type": "application/json"
        }
        response = requests.post(url=url, data=json.dumps(data), headers=headers)
        qs = json.loads(response.text)
        # print(qs)
        print((api, qs['message'], qs['data']))

    2-5、基于requests模块发起ajax(get)请求-略

    省略。跟requests发get请求一模一样,只是ajax返回的数据长度比较短

    2-6、基于requests模块发起ajax(post)请求-略

    省略。跟requests发post请求一模一样,只是ajax返回的数据长度比较短

    2-7、requests模块综合练习

    例如:爬取搜狗->知乎中"人工智能"词条搜索结果前3页的数据

    import requests
    url = "https://www.sogou.com/sogou
    for page in range(1,4):
    params = {
    "query": "人工智能",
    "pid": "sogou-wsse-ff111e4a5406ed40",
    "insite": "zhihu.com",
    "sut": "3651",
    "lkt": "0,0,0",
    "sst0": "1561710969623",
    "page": "2",
    "duppid": "1",
    "ie": "utf8",
    }
    response = requests.get(url,params=params)
    print(response.text)

    三、requests模块高级

    3.1、cookie

    1.执行登录操作(获取cookie)
    2.在发起个人主页请求时,需要将cookie携带到该请求中
    登录的时候服务器发送的cookie存放在浏览器session中。

    3.2、cookie操作:获取某用户的个人主页(先登录再获取)

    import requests
    session = requests.session()
    url = "https://movie.douban.com/login/"
    data =
    "source":"movie",
    "redir":"https://movie.douban.com/",
    "form_email":15203949239,
    "form_password":hh12345,
    "login":"登录",
    }
    # 登录
    session.post(url=url,data=data,headers=headers)
    url="https://www.douban.com/people"
    # 个人主页
    response = session.get(url=url)
    page_text = response.text

    3.3、代理(正向代理)

    1.爬虫中为什么要使用代理?反反爬手段
    2.有些门户网站会监测某IP的次数,次数太快会被禁
    3.免费代理IP的网站提供商www.goubanjia.com

    3.4、代理操作:更换IP然后向百度搜索的IP关键字发请求,看IP所在地

    import requests
    # url的协议和proxy的协议保持一致,都为http。
    url = 'http://www.baidu.com/s?ie=utf-8&wd=ip'
    proxy = {
    'http':'77.73.69.120:3128'
    }
    # 更换网络IP
    request = requests.get(url=url,proxies=proxy)

    四、验证码处理-打码平台

    使用云打码平台自动识别验证码,实现流程:
    1.对携带验证码的页面数据进行抓取
    2.可以将页面数据中验证码进行解析,验证码图片下载到本地
    3.可以将验证码图片提交给第三方平台进行识别,返回验证码图片上的数据值
    云打码平台
    1,在官网进行注册(普通用户和开发者用户)
    2,登录开发者用户
    3,在开发文档中下载示例代码(调用示例及最新的dll)
    4,下载“pythonHTTP示例下载”
    5,创建一个软件:我的软件->添加新软件->提交-产生秘钥数据
    6,使用示例代码中的源码文件中的代码进行修改,让其识别验证码图片
    7,解压下载的示例代码里面的YDMHTTPDemo3.x.py
    8,拷贝YDMHTTPDemo3.x.py中YDMHttp类到你的代码中,注册
    9,import json,time 打码平台要用到这两个模块
    10,拷贝YDMHTTPDemo3.x.py中剩下的代码,封装到get_img_code(img_obj)方法中
    username=你第一步注册的普通用户,里面的剩余题分是你可以识别的次数
    password=普通用户的密码
    appid = 你的开发者用户的软件代码
    appkey = 你的开发者用户的软件秘钥
    filename = 你的验证码图片路径
    codetype = 验证码类型,例如4位纯英文等
    timeout = 超时时间一般为20
    return result


    import requests
    from lxml import etree
    url="https://www.douban.com/accounts/login?source=movie"
    page_text = requests.get(url=url)
    # 获取验证码图片
    tree = etree.HTML(page_text)
    codeImg_url = tree.xpath('//*[@id="captcha_image"]/@src')[0]
    code_img = requests.get(url=codeImg_url).content
    with open("./code.png","wb") as fp:
    fp.write(code_img)
    code_text = getCode('./code.png')

    附加知识点:xpath解析HTML代码

    1.下载:pip install lxml
    2.导包:from lxml import etree
    3.将html文档或者xml文档转换成一个etree对象,然后调用对象中的方法查找指定的节点
      2.1 本地文件:tree = etree.parse(文件名)
    tree.xpath("xpath表达式")
      2.2 网络数据:tree = etree.HTML(网页内容字符串)
    tree.xpath("xpath表达式")

    常用xpath表达式:
    属性定位:
    #找到class属性值为song的div标签
    //div[@class="song"]
    取属性:
    # 找到class属性值为tang的div标签下第二个li标签下的a标签的href属性值
    //div[@class="tang"]//li[2]/a/@href
    层级&索引定位:
    #找到class属性值为tang的div的直系子标签ul下的第二个子标签li下的直系子标签a
    //div[@class="tang"]/ul/li[2]/a
    逻辑运算:
    #找到href属性值为空且class属性值为du的a标签
    //a[@href="" and @class="du"]
    模糊匹配:
    //div[contains(@class, "ng")]
    //div[starts-with(@class, "ta")]
    取文本:
    # /表示获取某个标签下的文本内容
    # //表示获取某个标签下的文本内容和所有子标签下的文本内容
    //div[@class="song"]/p[1]/text()
    //div[@class="tang"]//text()

  • 相关阅读:
    iOS设计模式:观察者
    Java面向接口编程小例子
    《The DeadLine》(《最后期限》) 读后感
    Codeforces Round #395 Div1的A题Timofey and a tree
    重写和强制转换再调用能编译但不能运行
    Java继承和静态-加载顺序
    C++之pair
    用Java面向对象思想实现一个微博的功能(未完)
    Java对象在内存图示
    Java中OOP对象和引用
  • 原文地址:https://www.cnblogs.com/staff/p/10768473.html
Copyright © 2020-2023  润新知