爬蟲數據解析的三種方式


一、正則表達式解析

https://www.cnblogs.com/Zzbj/p/9622310.html

https://www.cnblogs.com/Zzbj/p/9629299.html

https://www.cnblogs.com/Zzbj/p/9630218.html

 

1、簡單介紹

單字符:
    .      匹配除換行符以外的任意字符

    \w     匹配字母或數字或下划線
    \d     匹配數字
    \s     匹配任意的空白符

    \W     匹配非字母或數字或下划線
    \D     匹配非數字
    \S     匹配非空白符

    \n     匹配一個換行符
    \t     匹配一個制表符(Tab)

    \b     匹配一個邊界(其前后必須是不同類型的字符,
           可以組成單詞的字符為一種類型,
           不可組成單詞的字符(包括字符串的開始和結束)為另一種類型)

    a|b    匹配字符a或字符b

    ()     匹配括號內的表達式,一個組表示一個整體

    [...]  匹配字符組中的字符
    [^...] 匹配除了字符組中字符的所有字符

數量修飾:
    * : 任意多次  >=0
    + : 至少1次   >=1
    ? : 可有可無  0次或者1次
    {m} :固定m次 hello{3,}
    {m,} :至少m次
    {m,n} :m到n次

邊界:
    $ : 以某某結尾 
    ^ : 以某某開頭

貪婪模式: .*
非貪婪(惰性)模式: .*?

re模塊:
    1.匹配方法
    re.findall(正則, 字符串)  # 返回一個匹配到所有結果的列表
    re.search(正則, 字符串)  # 返回一個對象,用group()取值,只匹配一個結果
    re.match(正則, 字符串)  # 返回一個對象,用group()取值,只匹配一個結果,且默認正則有  ^  以什么開頭
    
    re.finditer(正則, 字符串)  # 返回一個存放匹配結果的迭代器(節省內存)
    例如:
    ret = re.finditer('\d+','qwe123abc456')
    print(ret)  # <callable_iterator object at 0x000001CA560DF860>
    print(ret.__next__().group())   # 123
    print(next(ret).group())        # 456

    # 或者單獨使用for
    for i in ret:
        print(i.group())  #   123  456

    compile:將正則表達式編譯成為一個正則表達式對象
    com = re.compile('\d+')
    print(com)  # re.compile('\\d+')

    ret = com.search('qwe123abc456')
    print(ret.group())  # 123

    ret = com.findall('qwe123abc456')
    print(ret)     # ['123', '456']

    ret = com.finditer('qwe123abc456')
    for i in ret:
        print(i.group())  #  123  456 


    2.其他內容
    優先顯示分組內容()
    
    ?的應用
    ? 表示量詞,零次或者一次
    (?:正則表達式) 表示取消優先顯示功能
    (?P<組名>正則表達式) 表示給這個組起一個名字
    (?P=組名) 表示引用之前組的名字,引用部分匹配到的內容必須和之前那個組中的內容一模一樣

    re.I : 忽略大小寫
    re.M :多行匹配
    re.S :單行匹配

    re.sub(正則表達式, 替換內容, 字符串)
    re.split(正則表達式, 字符串)

 

二、Xpath解析

1、什么是Xpath

XPath 是一門在 XML 文檔中查找信息的語言。XPath 用於在 XML 文檔中通過元素和屬性進行導航。

XPath 使用路徑表達式在 XML 文檔中進行導航
XPath 包含一個標准函數庫
XPath 是 XSLT 中的主要元素
XPath 是一個 W3C 標准

 

2、Xpath的使用

1.下載:pip install lxml
2.導包:from lxml import etree

3.將html文檔或者xml文檔轉換成一個etree對象,然后調用對象中的方法查找指定的節點
  3.1 本地文件:tree = etree.parse(文件名)
                tree.xpath("xpath表達式")

  3.2 網絡數據:tree = etree.HTML(網頁內容字符串)
                tree.xpath("xpath表達式")

 

三、Xpath的語法

摘抄自w3school教程:http://www.w3school.com.cn/xpath/xpath_syntax.asp

1、xpath語法

表達式 描述
nodename 選取此節點的所有子節點。
/ 從根節點選取。
// 從匹配選擇的當前節點選擇文檔中的節點,而不考慮它們的位置。
. 選取當前節點。
.. 選取當前節點的父節點。
@ 選取屬性。

 

以下面這個xml為例子

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore>

xml.xpath(“bookstore”) 表示選取 bookstore 元素的所有子節點

xml.xpath(“/bookstore”) 表示選取根元素 bookstore。

xml.xpath(“bookstore/book”) 選取屬於 bookstore 的子元素的所有 book 元素。

xml.xpath(“//book”) 選取所有 book 子元素,而不管它們在文檔中的位置。

xml.xpath(“bookstore//book”) 選擇屬於 bookstore 元素的后代的所有 book 元素,而不管它們位於 bookstore 之下的什么位置。

xml.xpath(“//@lang”) 選取名為 lang 的所有屬性。

 

2、謂語

路徑表達式 結果
/bookstore/book[1] 選取屬於 bookstore 子元素的第一個 book 元素。
/bookstore/book[last()] 選取屬於 bookstore 子元素的最后一個 book 元素。
/bookstore/book[last()-1] 選取屬於 bookstore 子元素的倒數第二個 book 元素。
/bookstore/book[position()<3] 選取最前面的兩個屬於 bookstore 元素的子元素的 book 元素。
//title[@lang] 選取所有擁有名為 lang 的屬性的 title 元素。
//title[@lang=’eng’] 選取所有 title 元素,且這些元素擁有值為 eng 的 lang 屬性。
/bookstore/book[price>35.00] 選取 bookstore 元素的所有 book 元素,且其中的 price 元素的值須大於 35.00。
/bookstore/book[price>35.00]/title 選取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值須大於 35.00。

 

3、選取未知節點

通配符 描述
* 匹配任何元素節點。
@* 匹配任何屬性節點。
node() 匹配任何類型的節點。

例子:

路徑表達式 結果
/bookstore/* 選取 bookstore 元素的所有子元素。
//* 選取文檔中的所有元素。
//title[@*] 選取所有帶有屬性的 title 元素。

 

4、選取若干路徑

通過在路徑表達式中使用“|”運算符,您可以選取若干個路徑。

路徑表達式 結果
//book/title | //book/price 選取 book 元素的所有 title 和 price 元素。
//title | //price 選取文檔中的所有 title 和 price 元素。
/bookstore/book/title | //price 選取屬於 bookstore 元素的 book 元素的所有 title 元素,以及文檔中所有的 price 元素。

 

5、軸

軸可定義相對於當前節點的節點集。

軸名稱 結果
ancestor 選取當前節點的所有先輩(父、祖父等)。
ancestor-or-self 選取當前節點的所有先輩(父、祖父等)以及當前節點本身。
attribute 選取當前節點的所有屬性。
child 選取當前節點的所有子元素。
descendant 選取當前節點的所有后代元素(子、孫等)。
descendant-or-self 選取當前節點的所有后代元素(子、孫等)以及當前節點本身。
following 選取文檔中當前節點的結束標簽之后的所有節點。
namespace 選取當前節點的所有命名空間節點。
parent 選取當前節點的父節點。
preceding 選取文檔中當前節點的開始標簽之前的所有節點。
preceding-sibling 選取當前節點之前的所有同級節點。
self 選取當前節點。

 

步的語法:
軸名稱::節點測試[謂語]

 

例1:

例子 結果
child::book 選取所有屬於當前節點的子元素的 book 節點。
attribute::lang 選取當前節點的 lang 屬性。
child::* 選取當前節點的所有子元素。
attribute::* 選取當前節點的所有屬性。
child::text() 選取當前節點的所有文本子節點。
child::node() 選取當前節點的所有子節點。
descendant::book 選取當前節點的所有 book 后代。
ancestor::book 選擇當前節點的所有 book 先輩。
ancestor-or-self::book 選取當前節點的所有 book 先輩以及當前節點(如果此節點是 book 節點)
child::*/child::price 選取當前節點的所有 price 孫節點。

 

 例2:

原文:https://blog.csdn.net/qq_37059367/article/details/83819828 

<div>
    <a id="1" href="www.baidu.com">我是第1個a標簽</a>
    <p>我是p標簽</p>
    <a id="2" href="www.baidu.com">我是第2個a標簽</a>
    <a id="3" href="www.baidu.com">我是第3個a標簽</a>
    <a id="4" href="www.baidu.com">我是第4個a標簽</a>
    <p>我是p標簽</p>
    <a id="5" href="www.baidu.com">我是第5個a標簽</a>
</div>
獲取第三個a標簽的下一個a標簽:"//a[@id='3']/following-sibling::a[1]"

獲取第三個a標簽后面的第N個標簽:"//a[@id='3']/following-sibling::*[N]"

獲取第三個a標簽的上一個a標簽:"//a[@id='3']/preceding-sibling::a[1]"

獲取第三個a標簽的前面的第N個標簽:"//a[@id='3']/preceding-sibling::*[N]"

獲取第三個a標簽的父標簽:"//a[@id=='3']/.."

 

6、功能函數

使用功能函數能夠更好的進行模糊搜索

函數                  用法                                                               解釋
starts-with         xpath('//div[starts-with(@id,"ma")]')                        選取id值以ma開頭的div節點
contains            xpath('//div[contains(@id,"ma")]')                           選取id值包含ma的div節點
and                 xpath('//div[contains(@id,"ma") and contains(@id,"in")]')    選取id值包含ma和in的div節點
text()              xpath('//div[contains(text(),"ma")]')                        選取節點文本包含ma的div節點

 

7、Element對象

from lxml.etree import _Element
for obj in ret:
    print(obj)
    print(type(obj))  # from lxml.etree import _Element

# 用xpath語法查詢出來的列表,里面的對象都是Element對象
 Element對象的內置方法如下: class xml.etree.ElementTree.Element(tag, attrib={}, **extra)

  tag:string,元素代表的數據種類。
  text:string,元素的內容。
  tail:string,元素的尾形。
  attrib:dictionary,元素的屬性字典。
  
  #針對屬性的操作
  clear():清空元素的后代、屬性、text和tail也設置為None。
  get(key, default=None):獲取key對應的屬性值,如該屬性不存在則返回default值。
  items():根據屬性字典返回一個列表,列表元素為(key, value)。
  keys():返回包含所有元素屬性鍵的列表。
  set(key, value):設置新的屬性鍵與值。

  #針對后代的操作
  append(subelement):添加直系子元素。
  extend(subelements):增加一串元素對象作為子元素。#python2.7新特性
  find(match):尋找第一個匹配子元素,匹配對象可以為tag或path。
  findall(match):尋找所有匹配子元素,匹配對象可以為tag或path。
  findtext(match):尋找第一個匹配子元素,返回其text值。匹配對象可以為tag或path。
  insert(index, element):在指定位置插入子元素。
  iter(tag=None):生成遍歷當前元素所有后代或者給定tag的后代的迭代器。#python2.7新特性
  iterfind(match):根據tag或path查找所有的后代。
  itertext():遍歷所有后代並返回text值。
  remove(subelement):刪除子元素。

 

8、常用xpath查詢示例

html_document = '''
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>測試bs4</title>
</head>
<body>
    <div>
        <p>百里守約</p>
    </div>
    <div class="song">

        <p>李清照</p>
        <p>王安石</p>
        <p>蘇軾</p>
        <p>柳宗元</p>
        <a href="http://www.song.com/" title="趙匡胤" target="_self">
            <span>this is span</span>
        宋朝是最強大的王朝,不是軍隊的強大,而是經濟很強大,國民都很有錢</a>
        <a href="" class="du">總為浮雲能蔽日,長安不見使人愁</a>
        <img src="http://www.baidu.com/meinv.jpg" alt="" />
    </div>
    <div class="tang">
        <ul>
            <li><a href="http://www.baidu.com" title="qing">清明時節雨紛紛,路上行人欲斷魂,借問酒家何處有,牧童遙指杏花村</a></li>
            <li><a href="http://www.163.com" title="qin">秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山</a></li>
            <li><a href="http://www.126.com" alt="qi">岐王宅里尋常見,崔九堂前幾度聞,正是江南好風景,落花時節又逢君</a></li>
            <li><a href="http://www.sina.com" class="du">杜甫</a></li>
            <li><a href="http://www.dudu.com" class="du">杜牧</a></li>
            <li><b>杜小月</b></li>
            <li><i>度蜜月</i></li>
            <li><a href="http://www.haha.com" id="feng">鳳凰台上鳳凰游,鳳去台空江自流,吳宮花草埋幽徑,晉代衣冠成古丘</a></li>
        </ul>
    </div>
</body>
</html>
'''
html_document
from lxml import etree

tree = etree.HTML(html_document)

# 找到class屬性值為song的div標簽
ret = tree.xpath("//div[@class='song']")

# 找到class屬性值為tang的div的直系子標簽ul下的第二個子標簽li下的直系子標簽a
ret = tree.xpath("//div[@class='tang']/ul/li[2]/a")

# 找到href屬性值為空且class屬性值為du的a標簽
ret = tree.xpath("//a[@class='du' and @href='']")

# 模糊匹配,找到class屬性包含'ng'的div標簽
ret = tree.xpath("//div[contains(@class,'ng')]")

# 模糊匹配,找到class屬性以'ta'開頭的div標簽
ret = tree.xpath("//div[starts-with(@class,'ta')]")

print(ret)  # ret是所有符合的Element對象組成的列表
for ele in ret:
    print(ele)
    print(ele.tag)
    print(ele.text)

# 還可以直接在找到的Element對象后面使用一些方法
ret = tree.xpath("//div[starts-with(@class,'ta')]/ul/li[1]/a/text()")
ret = tree.xpath("//div[starts-with(@class,'ta')]/ul/li[1]/a/@href")

for i in ret:
    print(i)

小結:
//    是不管節點在哪,都會去全局找
/     是在當節點向下找一層,就是只在當前節點的兒子里面找

 

四、BeautifulSoup

1、簡介

Beautiful Soup提供一些簡單的、python式的函數用來處理導航、搜索、修改分析樹等功能。
它是一個工具箱,通過解析文檔為用戶提供需要抓取的數據,因為簡單,所以不需要多少代碼就可以寫出一個完整的應用程序。

總而言之,Beautiful Soup是python的一個庫,最主要的功能是從網頁抓取數據
它能夠通過你喜歡的轉換器實現慣用的文檔導航,查找,修改文檔的方式,Beautiful Soup能為我們節省工作時間
需要注意的是Beautiful Soup 3 目前已經停止開發,官網推薦在現在的項目中使用Beautiful Soup 4。

 

2、安裝

1. 安裝beautifulsoup模塊

pip3 install beautifulsoup4

 

2. 安裝解析器

Beautiful Soup支持Python標准庫中的HTML解析器,還支持一些第三方的解析器,如果我們不安裝它,則 Python 會使用 Python默認的解析器,lxml 解析器更加強大,速度更快,推薦安裝。
pip3 install lxml


另一個可供選擇的解析器是純Python實現的 html5lib , html5lib的解析方式與瀏覽器相同
pip install html5lib

 

3. 解析器性能對比

 

4. 官方文檔
https://beautifulsoup.readthedocs.io/zh_CN/latest/

 

3、BS使用流程

導包:from bs4 import BeautifulSoup
使用方式:可以將一個html文檔,轉化為BeautifulSoup對象,然后通過對象的方法或者屬性去查找指定的節點內容
1. 轉化本地文件:
    soup = BeautifulSoup(open('本地文件'), 'lxml')

2. 轉化網絡文件:
    soup = BeautifulSoup('字符串類型或者字節類型', 'lxml')

3. soup對象即為html文件中的內容

 

五、BeautifulSoup的使用方法

html文檔:下面的例子都以這個文檔作為查詢的根本

html_doc ="""
<html>
    <head>
        <title>
            The Dormouse's story
        </title>
    </head>
    <body>
        <p class="title" id="myp">
            <b class="boldest" id="bbb">The Dormouse's story</b>
            <span><a href="" class="ming">xiaoming</a></span>
            <a href="">wanglin</a>
        </p>
        <p class="story">
            Once upon a time there were three little sisters; and their names were
            <a class="sister brother" href="http://example.com/elsie" id="link1">Elsie</a>
            <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
            <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
            and they lived at the bottom of a well.
        </p>
        <p class="story">
            ....
        </p>
    </body>
</html>
"""
html_doc
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'lxml')

BeautifulSoup找到的都是標簽對象

print(soup.prettify())  # 自動幫我們格式化補全改錯文檔

 

1、通過Tag(標簽名)找對象

soup.a  # 找到第一個a標簽

soup.body.b  # 找到第一個body標簽里面的b標簽

soup.find_all('a')  # 找到所有a標簽

 

2、attrs獲取tag的屬性

tag的屬性操作方法與字典一樣

soup.a.attrs  # 獲取第一個a標簽的所有屬性,返回一個字典
soup.a.attrs['class']  # 獲取第一個a標簽的class屬性
soup.a.attrs.get('class')  # 獲取第一個a標簽的class屬性
soup.a['class']  # 也可簡寫為這種形式

soup.a.name  # 獲取第一個a標簽的標簽名

 

3、添加/刪除/修改tag的屬性

soup.a['href'] = 'www.baidu.com'  # 修改屬性
print(soup.a['href'])  # www.baidu.com

soup.a['id'] = 1  # 增加屬性
print(soup.a.attrs['id'])  # 1

del soup.a['class']  # 刪除屬性
print(soup.a.attrs.get('class'))  # None

 

4、獲取標簽的內容

# 當p標簽下只有一個文本時(不嵌套其他標簽),可以取到內容,否則為None
print(soup.p.string)

# 拿到一個生成器對象, 取到p下所有的文本內容,有嵌套標簽也可以取
print(soup.p.strings)
for item in soup.p.strings:
    print(item)

# 取到p下所有的文本內容,有嵌套標簽也可以取
print(soup.p.text) 

# 跟上面的text一樣
print(soup.p.get_text())

# 取到文檔的所有文本內容,且去掉空白
for line in soup.stripped_strings:
    print(line)

 

5、遍歷文檔樹

# 1、嵌套選擇
print(soup.head.title.string)
print(soup.body.a.string)


# 2、子節點、子孫節點
print(soup.p.contents)  # p下所有子節點
print(soup.p.children)  # 得到一個迭代器,包含p下所有子節點

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

print(soup.p.descendants)  # 獲取子孫節點,p下所有的標簽都會選擇出來
for i, child in enumerate(soup.p.descendants):
    print(i, child)


# 3、父節點、祖先節點
print(soup.a.parent)  # 獲取a標簽的父節點
print(soup.a.parents)  # 找到a標簽所有的祖先節點,父親的父親,父親的父親的父親...


# 4、兄弟節點
print(soup.a.next_sibling)  # 下一個兄弟
print(soup.a.previous_sibling)  # 上一個兄弟

print(soup.a.next_siblings)  # 下面的兄弟們=>生成器對象
print(soup.a.previous_siblings)  # 上面的兄弟們=>生成器對象

 

6、5種過濾器

五種過濾器: 字符串、正則表達式、列表、True、方法

# 1、字符串:即標簽名
print(soup.find_all('b'))

# 2、正則表達式
import re
print(soup.find_all(re.compile('^b'))) #找出b開頭的標簽,結果有body和b標簽

# 3、列表:如果傳入列表參數,Beautiful Soup會將與列表中任一元素匹配的內容返回.下面代碼找到文檔中所有<a>標簽和<b>標簽:
print(soup.find_all(['a','b']))

# 4、True:可以匹配任何值,下面代碼查找到所有的tag,但是不會返回字符串節點
print(soup.find_all(True))
for tag in soup.find_all(True):
    print(tag.name)

# 5、方法:如果沒有合適過濾器,那么還可以定義一個方法,方法只接受一個元素參數 ,如果這個方法返回 True 表示當前元素匹配並且被找到,如果不是則反回 False
def has_class_but_no_id(tag):
    return tag.has_attr('class') and not tag.has_attr('id')

print(soup.find_all(has_class_but_no_id))

 

7、find_all()

find_all()是查找所有符合的標簽

# 1、按照屬性去查找
print(soup.find_all("a", href="http://example.com/lacie"))
print(soup.find_all("a", id="link3"))

# 1-2、特殊的屬性class:因為class是python的關鍵字,因此這里要查找class屬性要寫成:class_ 
# 注意關鍵字是class_,class_=value,value可以是五種選擇器之一
print(soup.find_all('a', class_='sister'))  # 查找類為sister的a標簽
print(soup.find_all('a',class_='sister brother'))  # 查找類為sister和brother的a標簽,順序錯誤也匹配不成功
print(soup.find_all(class_=re.compile('^sis')))  # 查找類為sis開頭的所有標簽

# 2、attrs
print(soup.find_all('p', attrs={'class': 'story'}))

# 3、text: 值可以是:字符,列表,True,正則
print(soup.find_all(text='Elsie'))
print(soup.find_all('a', text='Elsie'))

# 4、limit參數:如果文檔樹很大那么搜索會很慢.如果我們不需要全部結果,可以使用 limit 參數限制返回結果的數量.效果與SQL中的limit關鍵字類似,當搜索到的結果數量達到 limit 的限制時,就停止搜索返回結果
print(soup.find_all('a', limit=2))

# 5、recursive:調用tag的find_all()方法時,Beautiful Soup會檢索當前tag的所有子孫節點,如果只想搜索tag的直接子節點,可以使用參數 recursive=False .
print(soup.html.find_all('a'))
print(soup.html.find_all('a', recursive=False))

'''
像調用 find_all() 一樣調用tag
find_all() 幾乎是Beautiful Soup中最常用的搜索方法,所以我們定義了它的簡寫方法. BeautifulSoup 對象和 tag 對象可以被當作一個方法來使用,
這個方法的執行結果與調用這個對象的 find_all() 方法相同,下面兩行代碼是等價的:
soup.find_all("a")
soup("a")


這兩行代碼也是等價的:
soup.title.find_all(text=True)
soup.title(text=True)

'''

 

8、find()

find()是查找第一個符合的標簽,find_all的所有方法find也有一模一樣的。
print(soup.find("a", id="link1")) find_all() 方法將返回文檔中符合條件的所有tag,盡管有時候我們只想得到一個結果.比如文檔中只有一個
<body>標簽,那么使用 find_all() 方法來查找<body>標簽就不太合適, 使用 find_all 方法並設置 limit=1 參數不如直接使用 find() 方法.下面兩行代碼是等價的: soup.find_all('title', limit=1) soup.find('title') 唯一的區別是 find_all() 方法的返回結果是值包含一個元素的列表,而 find() 方法直接返回結果. find_all() 方法沒有找到目標是返回空列表, find() 方法找不到目標時,返回 None . print(soup.find("abcdefg")) # None soup.head.title 是 tag的名字方法的簡寫.這個簡寫的原理就是多次調用當前tag的 find() 方法: print(soup.head.title) # <title>The Dormouse's story</title> soup.find("head").find("title") # <title>The Dormouse's story</title> find和find_all的簡寫方式: soup.find("a") 等價於 soup.a soup.find_all("a") 等價於 soup("a") 特別需要注意的是,支持鏈式查找 soup.find("p").find_all("a") 等價於 soup.p("a")

 

9、css選擇器

CSS篩選器的語法是:標簽名不加任何修飾,類名前加點,id名前加 #
BS也給我們提供了跟CSS篩選器一模一樣的語法,用到的方法是 soup.select(),返回類型是 list

1.通過標簽名查找
print(soup.select("title"))
print(soup.select("b"))


2.通過類名查找
print(soup.select(".sister")) 


3.通過 id 名查找
print(soup.select("#myp"))


4.組合查找
print(soup.select("p #bbb"))  # 在p的子孫里面找id為bbb的標簽
print(soup.select("p>#bbb"))  # 只在p的兒子里面找id為bbb的標簽
print(soup.select("p.story"))  # 找到class為story的p標簽


5.屬性查找
print(soup.select("a[href='http://example.com/tillie']"))  # 找到href屬性值為http://example.com/tillie的a標簽

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM