爬蟲三種數據解析方式

三種方式:正則匹配、bs4解析、xpath解析php

 

1、正則解析

# 正則回顧
   單字符:
        . : 除換行之外全部字符
        [] :[aoe] [a-w] 匹配集合中任意一個字符
        \d :數字  [0-9]
        \D : 非數字
        \w :數字、字母、下劃線、中文
        \W : 非\w
        \s :全部的空白字符包,括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]。
        \S : 非空白
    數量修飾:
        * : 任意屢次  >=0
        + : 至少1次   >=1
        ? : 無關緊要  0次或者1次
        {m} :固定m次 hello{3,}
        {m,} :至少m次
        {m,n} :m-n次
    邊界:
        $ : 以某某結尾 
        ^ : 以某某開頭
    分組:
        (ab)  
    貪婪模式: .*
    非貪婪(惰性)模式: .*?

    re.I : 忽略大小寫
    re.M :多行匹配
    re.S :單行匹配        (經常使用)

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

回顧練習html

import re
key="javapythonc++php"
re.findall('python',key)[0]
#####################################################################
#提取出hello world
key="<html><h1>hello world<h1></html>"
re.findall('<h1>(.*)<h1>',key)[0]
#提取出http://和https://
key='http://www.baidu.com and https://boob.com'
re.findall('https?://',key)
#####################################################################
#提取出hello
key='lalala<hTml>hello</HtMl>hahah' #輸出<hTml>hello</HtMl>
re.findall('<[Hh][Tt][mM][lL]>(.*)</[Hh][Tt][mM][lL]>',key)
#############################################################
key='bobo@hit.edu.com'#想要匹配到hit.
re.findall('h.*?\.',key)
#####################################################################
#匹配sas和saas
key='saas and sas and saaas'
re.findall('sa{1,2}s',key)
#####################################################################
#匹配所有行
string1 = """<div>靜夜思
窗前明月光
疑是地上霜
舉頭望明月
低頭思故鄉
</div>"""

re.findall('.*',string1,re.S)

正則數據解析實例java

# 爬取糗事百科糗圖python

import requests
import re
from urllib import request
import os
url = 'https://www.qiushibaike.com/pic/'
header = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36"
}
# request.urlretrieve(url,'qiutu.jpg')
if  not os.path.exists('./qiutu'):
    os.mkdir('./qiutu')
response_obj = requests.get(url=url,headers=header).text
ex = '<div class=\"thumb\">.*?<img src=\"(.*?)\" alt=.*?</div>'
url_list = re.findall(ex,response_obj,re.S)
print(url_list)
for ur in url_list:
    all_url = 'https:' + ur
    name = ur.split('/')[-1]
    path = './qiutu/' + name
    request.urlretrieve(all_url,path)
    print(name,'下載完畢')
print('over')

2、 BeautifulSoup解析

環境安裝:linux

- 須要將pip源設置爲國內源,阿里源、豆瓣源、網易源等
   - windows
    (1)打開文件資源管理器(文件夾地址欄中)
    (2)地址欄上面輸入 %appdata%
    (3)在這裏面新建一個文件夾  pip
    (4)在pip文件夾裏面新建一個文件叫作  pip.ini ,內容寫以下便可
        [global]
        timeout = 6000
        index-url = https://mirrors.aliyun.com/pypi/simple/
        trusted-host = mirrors.aliyun.com
   - linux
    (1)cd ~
    (2)mkdir ~/.pip
    (3)vi ~/.pip/pip.conf
    (4)編輯內容,和windows如出一轍
- 須要安裝:pip install bs4
     bs4在使用時候須要一個第三方庫,把這個庫也安裝一下
     pip install lxml
  • 基礎使用
使用流程:       
    - 導包:from bs4 import BeautifulSoup
    - 使用方式:能夠將一個html文檔,轉化爲BeautifulSoup對象,而後經過對象的方法或者屬性去查找指定的節點內容
        (1)轉化本地文件:
             - soup = BeautifulSoup(open('本地文件'), 'lxml')
        (2)轉化網絡文件:
             - soup = BeautifulSoup('字符串類型或者字節類型', 'lxml')
        (3)打印soup對象顯示內容爲html文件中的內容

基礎鞏固:
    (1)根據標籤名查找
        - soup.a   只能找到第一個符合要求的標籤
    (2)獲取屬性
        - soup.a.attrs  獲取a全部的屬性和屬性值,返回一個字典
        - soup.a.attrs['href']   獲取href屬性
        - soup.a['href']   也可簡寫爲這種形式
    (3)獲取內容
        - soup.a.string
        - soup.a.text
        - soup.a.get_text()
       【注意】若是標籤還有標籤,那麼string獲取到的結果爲None,而其它兩個,能夠獲取文本內容
    (4)find:找到第一個符合要求的標籤
        - soup.find('a')  找到第一個符合要求的
        - soup.find('a', title="xxx")
        - soup.find('a', alt="xxx")
        - soup.find('a', class_="xxx")
        - soup.find('a', id="xxx")
    (5)find_all:找到全部符合要求的標籤
        - soup.find_all('a')
        - soup.find_all(['a','b']) 找到全部的a和b標籤
        - soup.find_all('a', limit=2)  限制前兩個
    (6)根據選擇器選擇指定的內容
               select:soup.select('#feng')
        - 常見的選擇器:標籤選擇器(a)、類選擇器(.)、id選擇器(#)、層級選擇器
            - 層級選擇器:
                div .dudu #lala .meme .xixi  下面好多級
                div > p > a > .lala          只能是下面一級
        【注意】select選擇器返回永遠是列表,須要經過下標提取指定的對象

beautifulsoup解析實例c++

# 爬取三國演義所有內容
import requests
from bs4 import BeautifulSoup
url = 'http://www.shicimingju.com/book/sanguoyanyi.html'
header = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
}
page_text = requests.get(url=url,headers=header).text
soup = BeautifulSoup(page_text,'lxml')
# 獲取每章的詳情url
a_list = soup.select('.book-mulu > ul > li > a')
# print('list',a_list)
f = open("sanguo.txt",'w',encoding='utf-8')
for a in a_list:
    # 章節題目
    title = a.string
    a_url = 'http://www.shicimingju.com'+a['href']
    a_page_text = requests.get(url=a_url,headers=header).text
    soup = BeautifulSoup(a_page_text,'lxml')
    # 章節內容
    content = soup.find('div',class_='chapter_content').text
    f.write(title+'\n'+content)
    print(title,'下載完畢')
   
print('over')
f.close()

3、Xpath解析

測試頁面數據正則表達式

<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>

表達式練習windows

屬性定位:
    #找到class屬性值爲song的div標籤
    //div[@class="song"] 
層級&索引定位:
    #找到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()
取屬性:
    //div[@class="tang"]//li[2]/a/@href

代碼中使用xpath表達式進行數據解析:
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解析實例網絡

# 抓取58二手房信息
import requests
import re
import os
from lxml import etree
url = 'https://bj.58.com/shahe/ershoufang/?utm_source=market&spm=u-2d2yxv86y3v43nkddh1.BDPCPZ_BT&PGTID=0d30000c-0047-eace-ec01-460ad4ec1202&ClickID=1'
header = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36"
}

response_obj = requests.get(url=url,headers=header).text
# print(response_obj)
tree = etree.HTML(response_obj)
li_list = tree.xpath('//ul[@class=\"house-list-wrap\"]/li')
# print(li_list)
all_data_list = []
for li in li_list:
    # 過濾信息
    title = li.xpath('./div[2]//a/text()')[0]
#     print(title)
    a_url = li.xpath('./div[2]//a/@href')[0]
    price = li.xpath('./div[3]//text()')
    price = ' '.join(price)
    if 'https' not in a_url:
        a_url = 'https:' + a_url
    page_text = requests.get(url=a_url,headers=header).text
    tree = etree.HTML(page_text)
    gaikuang = tree.xpath('//div[@id=\"generalSituation\"]//text()')
    gaikuang = ' '.join(gaikuang)
    house_msg = {
        "title":title,
        "price":price,
        "gaikuang":gaikuang
    }
    all_data_list.append(house_msg)
print(all_data_list)
相關文章
相關標籤/搜索