zoukankan      html  css  js  c++  java
  • 爬虫

    爬虫的原理

    先利用requests的get或者post从网页上获取请求,返回一个response对象,通过contents或text读取response文本内容形成html文档,然后利用beautifulsoup对html文档进行解析。

    Reuqests库

    requests支持两种网页获取方式,一种是requests.get(),一种是requests.post(),重要的是表头和其他参数,尤其表单数据。

    获取网页

    r = requests.get('https://api.github.com/events')
    r = requests.post('http://httpbin.org/post', data = {'key':'value'})

    传递URL参数

    像搜索引擎中搜索关键字可以通过传递URL参数关键字实现,以键值字符串来提供

    payload = {'key1':'value1','key2':'value2'}
    r = requests.get("http://httpbin.org/get",params = payload)
    print(r.url)

    http://httpbin.org/get?key2=value2&key1=value1

    响应内容

    获取网页后会得到一个response的对象,可以获取response对象的内容,大多数unicode字符集都能被无缝解码,如果出现中文乱码,则可以通过response.encoding查看文档编码,编码方式可以改变

    1 import requests
    2 r = requests.get('https://api.github.com/events')
    3 r.text 
    4 print(r.encoding)
    5 'utf-8' 
    6 r.encoding = 'ISO-8859-1' #更改文档编码方式

    除了获取response.text(unicode型数据)还可以获取response.content 二进制数据

    定制表头

    定制表头是为了模拟浏览器进行操作可以防止反爬虫,表头传入的是字典

    1 url = 'https://api.github.com/some/endpoint'
    2 headers = {'user-agent': 'my-app/0.0.1'}
    3 r = requests.get(url, headers=headers)

    定制表单

    对于动态网址经常会遇到翻页或URL不变的情况,通常影响因素就是表单,form_data

    form_data={'D1':'008'}
    page=requests.post(url,headers=headers,data=form_data)

    Beautifulsoup库

    主要是对html或者xml文档进行解析,支持两种文档解析方式,一种是利用find_all,一种是CSS解析,最关键的是里面属性的应用,包括tag,attrs,string,text,子节点和父节点的应用

    soup = beautifulsoup(html)

    beautifulsoup对象

    利用beautifulsoup()接口解析文档可以生成一个beautifulsoup对象,利用prettify()可以格式化输出

    四大对象种类

    Tag

    Tag 是html文档中的标签,可以直接使用soup.a获取第一个a标签。Tag有两个属性,一个是name,一个是attrs,其中attrs可以帮助我们定位tag,属于经常会用到的对象

    print soup.a
    #<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>

    NavigableString 

    naviablestring可以获取tag中的内部文字,soup.a.string,同时text函数也可以获取,二者的主要区别是string可以获取注释里的内部文字,但是text则不行

    1 test = '<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>'
    2 test1 = bs(test)
    3 test1.a.string #' Elsie '
    4 test1.a.text # ' '

    Comment

    comment是一种特殊的NavigableString对象,输出内容不包括注释符号,但是它的内部文字实际上是注释而不是直接的文字,注意navigablestring,text的区别

    遍历文档树

    解析完html文档生成文档树后,要对文档树进行遍历获取所需要的内容,常用的属性有Tag,Attrs,children,parents,contents,next_sibling,previous_sibling,next_element

    所搜文档树

    find_all(name,attrs,recursive,text,**kwargs),其中name通常指tag,可以传入列表['a','p']指满足任何一个tag即可,attrs是tag的属性通常和正则表达式或True结合使用,除此之外还可以传方法tag.has_attr(' ')表示tag是否有某个属性

    def has_class_but_no_id(tag):
        return tag.has_attr('class') and not tag.has_attr('id')
    
    soup.find_all(has_class_but_no_id)

    **keyword参数:如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索

    soup.find_all(id='link2')
    # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
    soup.find_all(href=re.compile("elsie"))
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]

     网页类型

    网页分为静态网页和动态网页,动态网页(ajax异步加载)要比静态网页复杂,主要提现在需要前后端交互,前端需要发送JS数据到服务器,服务器返回相应内容后由前端进行加载渲染成相应的页面,其地址栏中URL并不包含实际的html文档,可以通过XHR判断一个网页是不是ajax异步加载。通过network中的preview查看返回的相应URL。Ajax网页URL后通常会有"?"表示需要查询的内容,利用urlencode可以将网页和查询内容通过键值对的形式结合在一起。还有一种既不是AJAX异步加载,也不是静态网页,因为没有XHR,翻页或选择时URL不变,这时主要是通过表单数据控制,可以通过html中form查看。

    URL 中文编码

    URL只允许一部分ASCII字符(数字字母和部分符号),其他的字符(汉字)是不符合URL标准的,所以要对URL中特殊字符尤其汉字进行编码。在Python3.x中可以利用urllib.parse.quote(text,safe=string.printable)进行编码,safe表示哪些字符不会被编码,string.printable显示的一些字符。

    1 url = "http://www.ischoolbar.com/index.php/School/schools.html?province=1&provincename=北京"
    2 
    3 url_new = parse.quote(url,safe=string.printable)
    4 
    5 http://www.ischoolbar.com/index.php/School/schools.html?province=1&provincename=%E5%8C%97%E4%BA%AC

     Session和Cookie

    有的时候在不同的页面会出现request url相同的情况,通常情况下是通过cookie控制的,不同的Session会有不同的cookie,根据不同的cookie解析相同URL,返回的内容也会不同

    url_t = "http://www.ischoolbar.com/index.php/School/selectSchool.html?id=920&name=%E6%B5%99%E6%B1%9F%E5%A4%A7%E5%AD%A6"
    s = requests.Session()
    r = s.get(url_t)
    r_1 = s.get("http://www.ischoolbar.com/index.php/Goods/getGoods.html?pn=1")
    r_1.json()
  • 相关阅读:
    使用代理加快SDK Manager的下载速度
    ADT-Bundle运行的错误的排错
    转:Android开发之JNI入门-NDK从入门到精通
    Android NDK的总总误解
    mysql 数据库 一些常用语句 查内存 索引内存
    递归方法 练习编写
    ES 搜索概述
    PHP 数字类型 加 减 乘 除运算 bc函数
    php 控制反转 和 依赖注入
    Thinkphp 3 和 Thinkphp5 区别
  • 原文地址:https://www.cnblogs.com/mango-lee/p/9829171.html
Copyright © 2011-2022 走看看