ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python网络爬虫学习笔记(四)解析库的使用

2020-12-19 16:58:40  阅读:198  来源: 互联网

标签:Python 爬虫 li soup html print 解析 节点 属性


解析库的使用

使用正则表达式,比较烦琐,而且万一有地方写错了,可能导致匹配失败。
对于网页的节点来说,有 id 、 class 或其他属性。 而且节点之间还有层次关系,在网页中可以通过 XPath 或 css 选择器来定位一个或多个节点 。 利用 XPath 或 css选择器来提取某个节点,然后再调用相应方法获取它的正文内容或者属性。
在 Python 中,有 lxml 、Beautiful Soup 、 pyquery 等解析库实现这个操作。

使用 XPath

XPath , 全称 XML Path Language ,即 XML 路径语言,它是一门在 XML 文档中查找信息的语言 。
1. XPath 概览
XPath 提供了非常简洁明了的路径选择表达式,还提供了超过
100 个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等 。 几乎所有我们想要定位的节点,都可以用 XPath 来选择。
使用之前,首先要确保安装好 lxml 库
官方网站 : https://www.w3.org/TR/xpath

2. XPath 常用规则
在这里插入图片描述
例子:
//title[@lang=‘eng’]
代表选择所有名称为 title ,同时属性 lang 的值为 eng 的节点

实例引入

from lxml import etree
#一段 HTML 文本
text = '''		
<div>
<ul>
<li class="item-O"><a href="linkl.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a> 
</ul>
</div>
'''
#最后一个 li 节点是没有闭合的
html = etree.HTML(text) #调用 HTML 类进行初始化
result= etree.tostring(html)
print(result.decode('utf-8'))

调用 tostring ()方法即可输出修正后的 HTML 代码,但是结果是 bytes 类型 。 利用decode ()方法将其转成 str 类型,经过处理之后, li 节点标签被补全,并且还向动添加了 body 、 html 节点 。
运行结果:
在这里插入图片描述
也可以直接读取文本文件进行解析:

#输出结果略有不同,多了一个 DOCTYPE 的声明
html = etree.parse('. /test. html', etree.HTMLParser())
result= etree.tostring(html)

3.所有节点
用//开头的 XPath 规则来选取所有符合要求的节点

result = html.xpath('//*')

运行结果:
在这里插入图片描述
*代表匹配所有节点,也就是整个 HTML 文本中的所有节点都会被获取,返回形式是一个列表,每个元素是 Element 类型,其后跟了节点的名称,如 html 、 body 、 div 、 ul 、 li 、a等。
如果想获取所有 li 节点:

result = html.xpath('//li')
print(result)
print(result[0])

运行结果:
在这里插入图片描述
4. 子节点
通过 / 或 // 即可查找元素的子节点或子孙节点
其中/用于获取直接子节点,// 用于获取子孙节点

#选择 li 节点的所有直接 a 子节点
result = html.xpath('//li/a')

#取 ul 节点下的所有子孙 a 节点
result = html.xpath('//ul//a')

5.父节点
查找父节点可以用 … 来实现,也可以通过 parent ::来获取父节点

#选中 href 属性为 link4.html 的 a 节点,然后再获取其父节点,然后再获取其 class属性
result = html.xpath('//a[@href="link4.html"]/../@class')
result = html.xpath('//a[@href="link4.html"]/parent::*/@class')

6…属性匹配
可以用@符号进行属性过滤

#限制了节点的 class 属性为 item-0
result = html.xpath('//li[@class = "item-0"]')

7.文本获取
XPath 中的 text( )方法可获取节点中的文本

result = html.xpath('//li[@class = "item-0"]/text()')

没有获取到任何文本,只获取到了一个换行符:
因为 XPath 中text ()前面是/,而此处/的含义是选取直接子节点,很明显 l i 的直接子节点都是 a 节点,文本都是在a节点内部的,所以这里匹配到的结果就是被修正的li节点内部的换行符。
想获取 li 节点内部的文本,就有两种方式,一种是先选取 a 节点再获取文本,另一种就是使用 //

result1 = html.xpath('//li[@class = "item-0"]/a/text()')
result2 = html.xpath('//li[@class = "item-0"]//text()')
print(result1)
print(result2)

运行结果:
在这里插入图片描述
如果要想获取子孙节点内部的所有文本,可以直接用 //加 text( )的方式,这样可以保证获取到最全面的文本信息,但是可能会夹杂一些换行符等特殊字符。 如果想获取某些特定子孙节点下的所有文本,可以先选取到特定的子孙节点,然后再调用 text( )方法获取其内部文本,这样可以保证获取的结果是整洁的 。

8.属性获取
通过@href 即可获取节点的 href 属性
和属性匹配的方法不同,属性匹配是中括号加属性名和值来限定某个属性,如[@href="linkl.html”],而此处的@href 指的是获取节点的某个属性

result = html.xpath('//li/a/@href')

运行结果:
在这里插入图片描述
9.属性多值匹配
如果HTML 文本中 li 节点的 class 属性有两个值 li 和 li-first,此时如果还用之前的属性匹配获取,就无法匹配
这时就需要用 contains( )函数,第一个参数传人属性名称,第二个参数传入属性值,只要此属性包含所传入的属性值,就可以完成匹配了 。

result = html.xpath('//li[contains(@class,"li")]/a/text()')

10.多属性匹配
是根据多个属性确定一个节点,这时就需要同时匹配多个属性。 此时可以使用运算符 and 来连接:

result = html.xpath('//li[contains(@class,"li") and @name="item"]/a/text()')

同时根据 clas s 和 name 属性来选择,一个条件是 class 属性里面包含 li 字符串,另一个条件是 name 属性为 item 字符串,二者需要同时满足,用 and 操作符相连,相连之后置于中括号内进行条件筛选
在这里插入图片描述
11.按序选择
可以利用中括号传入索引的方法获取特定次序的节点

#选取第一个 li 节点,中括号中传入数字 l 
result = html.xpath('//li[l]/a/text()')

#选取最后一个 li 节点,中括号中传入 last()
result = html.xpath ('//li[last()]/a/text()')

#选取位置小于 3 的 li 节点
result = html.xpath('//li[position()<3]/a/text ()')

#选取倒数第三个 li 节点,中括号中传入 last()-2 
result = html.xpath('//li[last()-2]/a/text()')

在 XPath 中,提供了 100 多个函数,包括存取 、 数值、字符串、逻辑、节点、序列等处理功能,它们的具体作用可以参考: http://www.w3school.com.cn/xpath/xpath_functions.asp

12. 节点轴选择
XPath 提供了很多节点轴选择方法,包括获取子元素 、兄弟元素、父元素、祖先元素等

#调用ancestor 轴,可以获取所有祖先节点
result = html.xpath('//li[l]/ancestor::*')

#在冒号后面加了 div,得到的结果就只有 div 这个祖先节点
result = html.xpath('//li[l]/ancestor::div')

#调用了 attribute 轴,可以获取所有属性值,其后跟的选择器还是*,代表获取节点的所有属性,返回值就是 li 节点的所有属性值
result = html.xpath('//li[1]/attribute::*')

#调用了 child 轴,可以获取所有直接子节点,当前选取 href 属性为 linkl.html 的 a 节点
result= html.xpath('//li[1]/child::a[@href="linkl.html"]')

#调用了 descendant 轴,可以获取所有子孙节点,当前获取只包含 span 节点而不包含 a 节点 
result = html.xpath('li[l]/descendant::span')

#调用了 following 轴,可以获取当前节点之后的所有节点,当前只获取了第二个后续节点
result = html.xpath('//li[1]/following::*(2]')

#调用 了 following-sibling 轴 ,可以获取当前节点之后的所有同级节点,当前获取了所有后续同级节点
result = html.xpath('//li[1]/following-sibling::*')

更多 XPath 的用法,可以查看http://www.w3school.com.cn/xpath/index.asp
更多 .Python lxml 库的用法,可以查看 http://lxml.de/

使用 Beautiful Soup

Beautiful Soup 提供一些简 单的、 Python 式的 函数来处理导航、搜索、修改分析树等功能 。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序 。
Beautiful Soup 自动将输入文档转换为 Unicode 编码,输出文档转换为 UTF-8 编码 ,不需要考虑编码方式。

1.解析器
在这里插入图片描述
2. 基本用法

from bs4 import BeautifulSoup
soup = BeautifulSoup('<p>Hello</p>','lxml')
print (soup.prettify())
print(soup.p.string)

运行结果:
在这里插入图片描述
调用 prettify( )方法可以把要解析的字符串以标准的缩进格式输出,
对于不标准的 HTML 字符串 ,Beautifol Soup可以自动更正格式,在初始化 Beautifol Soup 时就完成了 。
soup.p.string可以选出 HTML 中的 p 节点,再调用 string 属性就可以得到里面的文本。

3.节点选择器
直接调用节点的名称就可以选择节点元素,再调用 string 属性就可以得到节点内的文本了
·选择元素
例子:

from bs4 import BeautifulSoup
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse" ><b>The Dormouse' s story</b></p>
<p class ="story">Once upon a time there were three little sisters; and their names were
<a href = "http://example.com/elsie" class= "sister" id =" linkl " >< ! ... Else ... ></a>
<a href = "http://example.com/eacie" class ="sister" id="link2" >Lacie</a> and
<a href = "http://example.com/tillie" class ="sister" id= "link3">Tillie</a>;
and they lived at the bottom of a well. </p>
<p class="story">... </p>
"""

soup = BeautifulSoup(html,'lxml')
print(soup.title)
print(type(soup.title))#经过选择器选择后,选择结果都是Tag 类型 
print(soup.title.string)#Tag 具有一些属性,比如 string,调用该属性,可以得到节点的文本内容
print(soup.head )
print(soup.p)

运行结果:
在这里插入图片描述
最后一个输出结果是第一个 p 节点的内容,后面的几个 p 节点并没有选到。所以,当有多个节点时,这种选择方式只会选择到第一个匹配的节点,其他的后面节点都会忽略。

·提取信息
(1)获取名称
可以利用 name 属性获取节点的名称 。

print(soup.title.name)

在这里插入图片描述
(2)获取属性
每个节点可能有多个属性,比如 id 和 class 等,选择这个节点元素后,可以调用 attrs 获取所有属性:

print(soup.p.attrs)
print(soup.p.attrs['name'])

在这里插入图片描述
attrs 的返回结果是字典形式,把选择的节点的所有属性和属性值组合成一个字典。
可以不用写 attrs ,直接在节点元素后面加中括号,传入属性名就可以获取属性值了。

print(soup.p['name'])
print(soup.p['class'])

在这里插入图片描述
根据属性的值是否唯一,有的返回结果是字符串,有的返回结果是字符串组成的列表。 对于 class , 一个节点元素可能有多个 class , 所以返回的是列表。

(3)获取内容
·嵌套选择
在 Tag 类型的基础上再次选择得到的依然还是 Tag 类型,每次返回的结果都相同,所以可以做嵌套选择 。

print(soup.head.title)
print(type(soup.head.title))
print(soup.head.title.string)

在这里插入图片描述
·关联选择
在做选择的时候,有时候不能做到一步就选到想要的节点元素,需要先选中某一个节点元素,然后以它为基准再选择它的子节点、父节点、 兄弟节点等。
(1)子节点和子孙节点
选取节点元素之后,如果想要获取它的直接子节点,可以调用 cont ents 属性

print(soup.p.contents) 

返回结果是列表形式,若该节点里既包含文本,又包含节点,最后会将它们以列表形式统一返回 。
注意:列表中的每个元素都是 p 节点的直接子节点。若直接子节点例包含子节点,返回结果不会把子孙节点选出来。
在这里插入图片描述
调用 children 属性得到相应的结果:

print(soup.body.children)
for i, child in enumerate(soup.body.children):
    print(i, child)

运行结果:
在这里插入图片描述
调用了 children 属性来选择,返回结果是生成器类型

要得到所有的子孙节点的话,可以调用 descendants 属性 :

print(soup.body. descendants)
for i, child in enumerate(soup.body. descendants):
    print(i, child)

在这里插入图片描述
(2)父节点和祖先节点
如果要获取某个节点元素的父节点,可以调用 parent 属性:

print(soup.a.parent)

在这里插入图片描述
这里输出的仅仅是 a 节点的直接父节点,而没有再向外寻找父节点的祖先节点 。如果想获取所有的祖先节点,可以调用 parents 属性 :

print(type(soup.a.parents))
print(list(enumerate(soup.a.parents)))

在这里插入图片描述
返回结果是生成器类型
(3)兄弟节点
next_sibling 和 previous_sibling 分别获取节点的下一个和上一个兄弟元素, next_siblings 和 previous_siblings 则分别返回所有前面和后面的兄弟节点的生成器

print(' next_sibling  ',soup.a.next_sibling )
print(' previous_sibling  ',soup.a.previous_sibling)
print(' next_siblings ',list(enumerate(soup.a.next_siblings)))
print(' previous_siblings  ',list(enumerate(soup.a.previous_siblings)))

在这里插入图片描述
(4)提取信息

print(soup.a.next_sibling.string)
print(list(soup.a.parents)[o].attrs['class'])

如果返回结果是单个节点,那么可以直接调用 string 、 attrs 等属性获得其文本和属性;如果返回结果是多个节点的生成器,则可以转为列表后取出某个元素,然后再调用 string 、 attrs 等属性获取其对应节点的文本和属性。
4.方法选择器
Beautifu l Soup 还提供了一些查询方法,比如 find_all()和 find ()等 ,调用它们,然后传入相应的参数,就可以灵活查询了。
• find_all()
查询所有符合条件的元素,给它传入一些属性或文本,就可以得到符
合条件的元素。
API 如下:
find_all(narne, attrs, recursive, text, **kwargs)
(l) name:根据节点名来查询元素

print(soup.find_all(name='p'))
print(type(soup.find_all(name='p')[0]))

在这里插入图片描述
调用 find_all ()方法,返回结果是列表类型,每个元素依然都是 bs4.element.Tag 类型,所以依然可以进行嵌套查询,可以再继续查询其内部的节点。

for p in soup.find_all(name = 'p'):
    print (p.find_all(name='a'))

在这里插入图片描述
(2) attrs

print(soup.find_all(attrs = {'id':'list-1'})
print(soup.find_all(attrs  = {'name': 'elements'})

对于一些常用的属性,比如 id 和 ιlass 等, 我们可以不用 attrs 来传递。 比如,要查询 id 为 list-1的节点,可以直接传人 id 这个参数。

print(soup.find_all(id='list-1'))
print(soup.find_all(class = 'element'))

(3) text
text 参数可用来匹配节点的文本 ,传入的形式可以是字符串,可以是正则表达式对象。

print(soup.find_all(text=re.compile('link')))
#结果返回所有匹配正则表达式的节点文本组成的列表

• find{)
与find_all( )方法比较,find()方法返回的是单个元素,即第一个匹配的元素。

print(soup.find(name = 'p'))
print(type(soup.find(name = 'p')))
print(soup.find(class_= 'list' ))

在这里插入图片描述

还有许多查询方法:
口 fiind_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( ):前者返回节点后所有符合条件的节点,后者返回第一个符合条件的节点 。

5.css 选择器
css官方文档地址: http://www.w3school.com.cn/cssref/css_selectors.asp
使用 css 选择器时,只需要调用 select( )方法,传人相应的 css 选择器即可。
例子:

from bs4 import BeautifulSoup
html = """
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element"> Foo</li>
<li class="element">Bar</li>
<li class="element">]ay</li>
</ul>
<Ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
"""
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]))

在这里插入图片描述
·嵌套选择

for ul in soup.select('ul'):
    print(ul.select('li'))

在这里插入图片描述
• 获取属性

直接传入中括号和属性名,以及通过 attrs 属性获取属性值,都可以成功 。

for ul in soup.select('ul'):
	print(ul['id'])
	print (ul.attrs['id'])

在这里插入图片描述

·获取文本

要获取文本,可以用 string 属性,还有一个方法就是 get_text()

for li in soup.select('li') :
    print('Get Text:',li.get_text())
    print('String:', li.string)

在这里插入图片描述

小总结:
1.推荐使用 lxml 解析库,必要时使用 html.parser。
2.节点选择筛选功能弱但是速度快 。
3.建议使用 find( )或者 find_all( )查询匹配单个结果或者多个结果 。
4.如果对 css 选择器熟悉的话,可以使用 select( )方法选择 。

使用 pyquery

如果比较熟悉css 选择器和jQuery,可以使用解析库一pyquery。

1.初始化
初始化 pyquery 的时候,需要传入 HTML 文本来初始化一个 PyQuery对象。 它的初始化方式有多种,比如直接传入字符串,传入 URL ,传人文件名,等等。
•字符串初始化

html = """
<div>
<ul>
<li class="item-O">first item</li>
<li class="item-1"><a herf = "link2.html"> second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class = cold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="links.html">fifth item</a></li>
</ul>
</div>
"""
from pyquery import PyQuery as pq  #引人 PyQuery 这个对象,取别名为 pq

#字符串当作参数传递给 PyQuery 类,完成了初始化
doc = pq(html)
print (doc('li'))

•URL 初始化

doc = pq(url='https://weibo.com')
print(doc('title'))

doc = pq(requests.get('https://weibo.com').text)#功能与上面相同
print(doc('title'))

在这里插入图片描述
•文件初始化
除了传递 URL ,还可以传递本地的文件名, 将参数指定为 filename 即可:

 doc = pq(filename='demo.html')

2.基本 css 选择器

html = """
<div id="container">
<ul class="list">
<li class="item-O">first item</li>
<li class="item-1"><a herf = "link2.html"> second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class = cold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="links.html">fifth item</a></li>
</ul>
</div>
"""
from pyquery import PyQuery as pq
import requests
doc = pq(html)
print(doc('#container .list li'))
print(type(doc('#container .list li')))

在这里插入图片描述

css 选择器#container .list li 的意思是先选取 id 为 container 的节点,然后再选取其内部的 class 为 list 的节点内部的所有 li 节点,然后,打印输出 ,它的类型依然是 PyQuery 类型。

3.查找节点
一些常用的查询函数和 jQuery 中函数的用法完全相同 。
·子节点
查找子节点时 , 需要用到find( )方法,传人的参数是 css 选择器。
find( )方法会将符合条件的所有节点选择出来,结果的类型是PyQuery 类型 。find( )的查找范围是节点的所有子孙节点,而如果只想查找子节点,那么可以用children( )方法。

items = doc('.list')
print(type(items))
print(items)
lis = items.find('li')
print(type(lis))
print(lis)

在这里插入图片描述

lis = items.children('li')
print(type(lis))
print(lis)

在这里插入图片描述

如果要筛选所有子节点中符合条件的节点,比如想筛选出子节点中 class 为 active 的节点,可以向 children()方法传入 css 选择器 .active:

lis = items.children('.active')
print(lis)

在这里插入图片描述
·父节点

#这里的父节点是该节点的直接父节点,
container = items.parent()
print(type(container))
print(container)

在这里插入图片描述
祖先节点:parents( )方法
·兄弟节点
siblings( )方法
如果要筛选某个兄弟节点,我们依然可以向 siblings 方法传入 css 选择器

4.遍历
对于多个节点的结果,就需要遍历来获取,可调用 items( )方法得到一个生成器,遍历一下,就可以逐个得到节点对象:

lis = doc('li').items()
print(type(lis))
for li in lis:
	print(li, type(li))

在这里插入图片描述

5.获取信息
比较重要的信息有两类, 一是获取属性,二是获取文本。
·获取属性
以调用 attr( )方法来获取属性:

a = doc(' .item-0.active a')
print(a, type(a))
print(a.attr('href'))
#也可以通过调用 attr 属性来获取属性
print(a.attr.href)

在这里插入图片描述
当返回结果包含多个节点时,调用 attr()方法,只会得到第一个节点的属性。遇到这种情况时,如果想获取所有的 a 节点的属性,就要遍历 :

a = doc('a')
for item in a.items() :
	print(item.attr('href'))

在这里插入图片描述
·获取文本
可以调用 text( )方法以获取其内部的文本信息 ,此时会忽略掉节点内部包含的所有 HTML,只返回纯文字内容。
html( )方法可以获取这个节点内部的 HTML 文本。
html( )方法返回的是第一个节点的内部 HTML 文本,而 text( )则返回了所有的节点内部的纯文本。

6.节点操作
pyquery 提供了一系列方法来对节点进行动态修改,比如为某个节点添加一个 class ,移除某个节点等。
例子:
• addClass 和 removeClass

li = doc('.item-0.active')
print(li)
li.removeClass('active')
print(li)
li.addClass('active')
print(li)

首先选中了第三个 li 节点,然后调用 removeClass( )方法,将 li 节点的active 这个 class 移除,后来又调用 addClass( )方法,将 class 添加回来。
在这里插入图片描述
• attr 、 text 和 html
除了操作 class 这个属性外,也可以用 attr( )方法对属性进行操作 。还可以用 text()和 html( )方法来改变节点内部的内容。

li = doc('.item-0.active')
print(li)
li.attr('name','link1')
print(li)
li.text('changed item')
print(li)
li.html('<span>changed item</span>')
print(li)

在这里插入图片描述
因此 attr( )方法只传入第一个参数的属性名,则是获取这个属性值 ; 如果传入第二个参数,可以用来修改属性值。 text( )和 html( )方法如果不传参数 ,则是获取节点内纯文本和 HTML 文本;如果传人参数 ,则进行赋值。

• remove()
remove( )方法就是移除

li = doc('.item-0')
print(li)
li.find('span').remove()
print(li)

在这里插入图片描述
还有很多节点操作的方法,比如 append ( )、 empty( )和 prepend( )等方法,它们和 jQuery的用法完全一致,详细的用法可以参考官方文档: http://pyquery.readthedocs.io/en/latest/api.html

7.伪类选择器
CSS3 的伪类选择器功能强大
例如选择第一个节点、最后一个节点、奇偶数节点、包含某一文本的节点等

li = doc('li:first-child')#第一个 li 节点
print(li)
li = doc('li:last-child')#最后一个 li 节点
print(li)
li = doc('li:nth-child(2)')#第二个 li节点
print(li)
li = doc('li:gt(2)')#第三个 li 之后的 li 节点
print(li)
li = doc('li:nth-child(2n)')#偶数位置的 li 节点
print(li)
li = doc('li:contains(second)')#
print(li)

关于 css 选择器的更多用法,可以参考 http://www.w3school.com.cn/css/index.asp
pyquery 的官方文档: http://pyquery.readthedocs.io

标签:Python,爬虫,li,soup,html,print,解析,节点,属性
来源: https://blog.csdn.net/qq_42138271/article/details/111149069

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有