• python爬虫笔记


    爬虫

    http://httpbin.org/  验证请求

    1.urllib库(python3)

    python内置的HTTP请求库

    urllib.request  请求模块 (https://yiyibooks.cn/xx/python_352/library/urllib.request.html#module-urllib.request)

    urllib.error      异常处理模块(https://yiyibooks.cn/xx/python_352/library/urllib.error.html#module-urllib.error)

    urllib.parse    url解析模块(https://yiyibooks.cn/xx/python_352/library/urllib.parse.html#module-urllib.parse)

    urllib.robotparser    robots.txt解析模块(https://yiyibooks.cn/xx/python_352/library/urllib.robotparser.html#module-urllib.robotparser)

    请求:

    import urllib.request

    urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None) 

    • url    请求的网址
    • data  加上以post请求发送,不加以get请求发送
    • [timeout, ]*     设置请求时间   超过时间报TIME OUT异常
    • cafile      
    • capath
    • cadefault
    • context

    响应 

    import urllib.request
    response = urllib.request.urlopen('https://www.python.org')
    print(type(response))#响应类型
    print(response.status)#状态码
    print(response.getheaders())#响应头 返回元组组成的列表
    print(response.getheader('Server'))#获取特定的响应头
    print(response.read().decode('utf-8'))#获得响应体

      也可以根据请求来获得响应

    from urllib import request, parse
    url = 'http://httpbin.org/post'
    headers = {
        'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
        'Host': 'httpbin.org'
    }
    dict = {
        'name': 'Germey'
    }
    data = bytes(parse.urlencode(dict), encoding='utf8')
    req = request.Request(url=url, data=data, headers=headers, method='POST')
    response = request.urlopen(req)
    print(response.read().decode('utf-8'))

     Handler

    代理ip

    proxy_handler = urllib.request.ProxyHandler({
        'http': 'http://127.0.0.1:9743',
        'https': 'https://127.0.0.1:9743'
    })
    opener = urllib.request.build_opener(proxy_handler)
    response = opener.open('http://httpbin.org/get')
    print(response.read())

    cookie(保持登录会话信息

    import http.cookiejar, urllib.request
    cookie = http.cookiejar.CookieJar()#也可以修改CookieJar把cookie保存到本地文件(MozillaCookieJar或LWPCookieJar)
    handler = urllib.request.HTTPCookieProcessor(cookie)
    opener = urllib.request.build_opener(handler)
    response = opener.open('http://www.baidu.com')
    for item in cookie:
        print(item.name+"="+item.value)

     异常

    from urllib import request, error
    try:
        response = request.urlopen('http://bubaidu.com/index.htm')
    except error.HTTPError as e:
        print(e.reason, e.code, e.headers, sep='
    ')
    except error.URLError as e:
        print(e.reason)
    else:
        print('Request Successfully')

    url解析

    urlparse

    urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)#urlstring:请求地址,scheme:约束 协议,allow_fragments:将fragment拼接到前面有数据的
    from urllib.parse import urlparse
    result = urlparse('http://www.baidu.com/index.html;user?id=5#comment', scheme='https',allow_fragments=False)
    print(type(result),result)
    ---------------------------------------------------------------------
    <class 'urllib.parse.ParseResult'> ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5#comment', fragment='')

    urlunparse(将url和参数请求等进行拼接

    urljoin(将两个url进行拼接,以后面的为基准)

    urlencode(将字典拼接为url的请求参数

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

    2.requests库

    (request库在urllib3的基础上进行加强,推荐使用request库)

    pip install requests
    import requests
    response = requests.get('https://www.baidu.com/')
    print(type(response))
    print(response.status_code)#响应状态码
    print(type(response.text))
    print(response.text)#响应体
    print(response.cookies)#cookies

    请求

      get请求

    requests.get(url, params=None, **kwargs)#params以字典形式添加请求参数,也可以直接在url中写参数
    #可以添加headers(有些网址不添加headers会报500的错误)

     headers = {
     'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
     }
     response = requests.get("https://www.zhihu.com/explore", headers=headers)

        解析json

    import requests
    import json
    response = requests.get("http://httpbin.org/get")
    print(type(response.text))
    print(response.json())
    print(json.loads(response.text))#用json转码,结果和response.json()返回结果一样
    print(type(response.json()))

        获取二进制数据(用于下载图片等)

    import requests
    response = requests.get("https://github.com/favicon.ico")
    with open('favicon.ico', 'wb') as f:#将图片保存到本地
        f.write(response.content)#获得图片的二进制内容并写入
        f.close()

      基本post请求

    import requests
    data = {'name': 'germey', 'age': '22'}
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
    }
    response = requests.post("http://httpbin.org/post", data=data, headers=headers)
    print(response.json())

    响应

    response = requests.get('http://www.jianshu.com')
    print(type(response.status_code), response.status_code)#状态码
    print(type(response.headers), response.headers)#响应头(字典)
    print(type(response.cookies), response.cookies)#cookies(列表)
    print(type(response.url), response.url) #
    print(type(response.history), response.history)#访问的历史记录

    文件上传

    files = {'file': open('favicon.ico', 'rb')}
    response = requests.post("http://httpbin.org/post", files=files)
    print(response.text)

    会话维持(模拟登陆)

    s = requests.Session()
    s.get('http://httpbin.org/cookies/set/number/123456789')
    response = s.get('http://httpbin.org/cookies')
    print(response.text)

    证书验证(在以https协议请求时,会先检测ssl是否是合法的)

    import requests
    from requests.packages import urllib3
    urllib3.disable_warnings()
    response = requests.get('https://www.12306.cn', verify=False)
    print(response.status_code)

    代理

    proxies = {
      "http": "http://127.0.0.1:9743",
      "https": "https://127.0.0.1:9743",
    }
    response = requests.get("https://www.taobao.com", proxies=proxies)
    print(response.status_code)

      也可以使用socks代理(pip3 install 'requests[socks]')

    proxies = {
        'http': 'socks5://127.0.0.1:9742',
        'https': 'socks5://127.0.0.1:9742'
    }

    超时设置

    response = requests.get("http://httpbin.org/get", timeout = 0.5)

    登录验证设置

    r = requests.get('http://120.27.34.24:9001', auth=('user', '123'))
    print(r.status_code)

    异常处理

    import requests
    from requests.exceptions import ReadTimeout, ConnectionError, RequestException
    try:
        response = requests.get("http://httpbin.org/get", timeout = 0.5)
        print(response.status_code)
    except ReadTimeout:
        print('Timeout')
    except ConnectionError:
        print('Connection error')
    except RequestException:
        print('Error')

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

    3.BeautifulSoup库

    pip install BeautifulSoup4

    解析库

    解析器使用方法优势劣势
    Python标准库 BeautifulSoup(markup, "html.parser") Python的内置标准库、执行速度适中 、文档容错能力强 Python 2.7.3 or 3.2.2)前的版本中文容错能力差
    lxml HTML 解析器 BeautifulSoup(markup, "lxml") 速度快、文档容错能力强 需要安装C语言库
    lxml XML 解析器 BeautifulSoup(markup, "xml") 速度快、唯一支持XML的解析器 需要安装C语言库
    html5lib BeautifulSoup(markup, "html5lib") 最好的容错性、以浏览器的方式解析文档、生成HTML5格式的文档 速度慢、不依赖外部扩展

    基本使用

    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html, 'lxml')
    print(soup.prettify())#格式化,补全代码
    print(soup.title.string)#输出title标签中的内容
    print(soup.title)#获取titile标签及其包裹的内容
    print(soup.title.name)#获取名称  结果为title
    print(soup.p.attrs['name'])#获取属性字段为的name的值
    print(soup.p['name'])#获取获取属性字段为的name的值
    print(soup.p.string)#获取p标签中的内容

      也可以嵌套选择

    print(soup.head.title.string)

      获得子节点和子孙节点方法

    #获得p标签子节点
        soup.p.contents#列表
        soup.p.children#迭代器
    #获得p标签所有子孙节点
        soup.p.descendants#迭代器

      例:

    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html, 'lxml')
    print(soup.p.children)
    for i, child in enumerate(soup.p.children):
        print(i, child)

      获得父节点和祖先节点

    soup.a.parent#获取a标签的父节点
    soup.a.parents#获取a标签的祖先节点(迭代器)

      获取兄弟节点

    soup.a.next_siblings#获取a标签后面的兄弟节点(迭代器)
    soup.a.previous_siblings#获取a标签前面的兄弟节点(迭代器)

    标准选择器

    find_all( name , attrs , recursive , text , **kwargs )#可根据标签名、属性、内容查找文档
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html, 'lxml')
    print(soup.find_all('ul'))#获取ul标签及内容,返回结果为列表
    
    print(soup.find_all(attrs={'id': 'list-1'}))#获取id为list-1的标签体,返回结果为列表
    print(soup.find_all(id='list-1'))#特殊的字段可以用这种形式,获取id为list-1的标签体,返回结果为列表
    print(soup.find_all(class_='element'))#class比较特殊
    
    print(soup.find_all(text='Foo'))#返回的结果:内容为Foo的元组 例['Foo', 'Foo'] (多用于匹配内容)
    find( name , attrs , recursive , text , **kwargs )#find返回单个元素,find_all返回所有元素
    find_parents()#返回所有祖先节点
    find_parent()# 返回直接父节点。
    
    find_next_siblings()#返回后面所有兄弟节点
    find_next_sibling()#返回后面第一个兄弟节点。
    
    find_previous_siblings()#返回前面所有兄弟节点
    find_previous_sibling()#返回前面第一个兄弟节点。
    
    find_all_next()#返回节点后所有符合条件的节点
    find_next()#返回第一个符合条件的节点
    
    find_all_previous()#返回节点后所有符合条件的节点
    find_previous()#返回第一个符合条件的节点

    CSS选择器

     通过select()直接传入CSS选择器即可完成选择

    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html, 'lxml')
    print(soup.select('.panel .panel-heading'))
    print(soup.select('ul li'))
    print(soup.select('#list-2 .element'))
    print(type(soup.select('ul')[0]))
      获取属性
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html, 'lxml')
    for ul in soup.select('ul'):
        print(ul['id'])
        print(ul.attrs['id'])
     获取内容
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html, 'lxml')
    for li in soup.select('li'):
        print(li.get_text())

    总结

    • 推荐使用lxml解析库,必要时使用html.parser
    • 标签选择筛选功能弱但是速度快
    • 建议使用find()、find_all() 查询匹配单个结果或者多个结果
    • 如果对CSS选择器熟悉建议使用select()
    • 记住常用的获取属性和文本值的方法

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

    4.pyquery库

    (pyquery比BeautifulSoup更加简易,熟悉jquery推荐使用pyquery)

    from pyquery import PyQuery as pq
    doc = pq(html)
    print(doc('li'))#打印所有li标签及内容(css选择器)

      URL初始化

    doc = pq(url='http://www.baidu.com')#将网页html代码作为参数

      文件初始化

    doc = pq(filename='demo.html')#这样写文件和代码在同一路径

    基本CSS选择器

    from pyquery import PyQuery as pq
    doc = pq(html)
    print(doc('#container .list li'))
    from pyquery import PyQuery as pq
    doc = pq(html)
    items = doc('.list')
    #查找元素
    lis = items.find('li')#查找子元素为li标签的
    lis2 = items.children('.active')#查找所有的直接子元素class为active的
    
    container = items.parent()#获取直接父元素
    parents = items.parents()#获取父节点及所有祖先节点,也可以添加选择器
    
    li = doc('.list .item-0.active')#.item-0.active表示一个整体 例:class="item-0 active"
    print(li.siblings())#获取所有的兄弟节点

    遍历

    from pyquery import PyQuery as pq
    doc = pq(html)#如果doc('li')获得为一个值则可以直接操作,如果多个可以进行遍历
    lis = doc('li').items()#转换为generator类型
    print(type(lis))
    for li in lis:
        print(li)

    获取信息

    from pyquery import PyQuery as pq
    doc = pq(html)
    a = doc('.item-0.active a')
    
    print(a.attr('href'))#获取属性为href的值
    print(a.attr.href)#获取属性为href的值
    
    print(a.text())#获取文本
    
    print(a.html())#获取HTML

    DOM操作

    from pyquery import PyQuery as pq
    doc = pq(html)
    li = doc('.item-0.active')
    
    #addClass、removeClass
    li.removeClass('active')#移除active属性
    li.addClass('active')#添加active属性
    
    #attr、css
    li.attr('name', 'link')#修改name属性的值(没有则添加,有则修改)
    li.css('font-size', '14px')#添加style属性并添加css样式
    
    #remove
    html = '''
    <div class="wrap">
        Hello, World
        <p>This is a paragraph.</p>
     </div>
    '''
    doc = pq(html)
    wrap = doc('.wrap')
    print(wrap.text())#Hello, World
               This is a paragraph.
    wrap.find('p').remove()#移除 print(wrap.text())#Hello, World

    其他DOM方法

     

     

  • 相关阅读:
    CSS Class 选择器
    CSS ID 选择器
    一个可以兼容各种数据库事务的使用范例
    参数化构造的通用查询方法
    QUI操作超时弹出登录窗口登录的处理方式
    一款代码生成器的妙用
    mongoDB操作命令及mongoDB的helper
    记录asp.net网站停止运行原因的代码
    一个JS版本的MD5
    获取地理位置的html5代码
  • 原文地址:https://www.cnblogs.com/jokerq/p/8870158.html
Copyright © 2020-2023  润新知