Beautifulsoup 爬取頁面試題

假設有一個頁面,頁面中有n道選擇題,每道選擇題有若干個選項。題幹部分用h6 標籤標記。選項部分用的是td 下的div 標籤。以下圖所示:html

整個頁面是將以下的HTML 段落循環n次。正則表達式

    
<div style="" class="qItemType qItemDetail1" value="10000#1" id="quest2436">                                    
    <div>
        <div class="breadcrumb">
            <div>
                <ul style="list-style-type:none;">
                    <li><h6><a name="qnum1" style="color: red;">第1題.</a>&nbsp;&nbsp;選一二三仍是四五六呢。</h6></li>
                </ul>
            </div>
            <ul style="list-style-type:none">
                <li>
                    <table>                                                
                        <tbody><tr>
                                 <td>
                                    <div>A.一二三</div>        
                                 </td>
                                </tr>
                                <tr>
                                  <td>
                                     <div>B.四五六</div>                    
                                  </td>
                                 </tr>                                            
                         </tbody></table>
                 </li>
            </ul>
        </div>            
<div>                                

 下面想要用beautifulsoup 庫中的方法將頁面上的題目和選項提取出來。數組

首先要引入須要用到的包:app

from bs4 import BeautifulSoup
from urllib import request,parse
import re

而後能夠用多種方法提取頁面源碼,:this

#既能夠打開一個html文件:
soup = BeautifulSoup(open("page_source_code.html"))
#或者直接傳入HTML代碼:
soup = BeautifulSoup("<html>data</html>")
#也能夠發送而且攔截請求:
url = 「http://fake.html」 response = request.urlopen(url,timeout = 20) responseUTF8 = response.read().decode("utf-8") soup = BeautifulSoup(responseUTF8,'lxml')

 總之,這樣咱們就獲得了一個soup 對象。接下來只要根據對象的標籤結構,經過必定方法定位到目標標籤,就能夠了。url

方法一:下面這種方法比較基本,用的是「絕對路徑」找尋標籤spa

# 經過觀察發現,題幹部分所有都是h6標籤,和h6標籤下的a標籤。頁面其他部分沒有用到h6標籤,因此用.find_all方法來抓取全部的題幹。獲得一個標籤 list
h6lbs = soup.find_all('h6')
# 定義一個二維數組,用來盛放抓取到的選擇題。選擇題的題乾和選項可做爲每個數組成員的成員。
item_question = []
for i in range(len(h6lbs)):
    #定義一個一維數組,能夠用來盛放題乾和選項。先把剛剛拿到的題幹保存進數組中
    item = []
    item.append(h6lbs[i].text)
    #經過以上的HTML 結構能夠知道,找到題幹後,題幹標籤的「太爺爺」的「三弟弟」是保存選項的地方,因此這裏用了不少個.parent 和 .next_sibling方法,經過絕對路徑的方式定位標籤
    tag1 = h6lbs[i].parent.parent.parent.next_sibling.next_sibling
    # check if this is choice question. or it must be a Yes/No questionnaire
    if tag1 is not None and tag1.li is not None:
        #剛剛說到太爺爺的三弟弟是存放選項的地方。太爺爺的三弟弟下的li標籤下的table標籤下的tbody標籤下存放了多個選項,從這裏開始須要遍歷,將每個選項都提取出
        tag = h6lbs[i].parent.parent.parent.next_sibling.next_sibling.li.table.tbody
        for child in tag.children:
            #由於抓取出來有空對象,因此此處加入了一個判斷。若是是None,就不保存了。
            if child.string is None:
                tag_string = child.td.div.string
                #遍歷每個標籤,取出其中的選項內容,用.string方法
                #將取到的選項內容加入剛剛建立的一維數組中
                item.append(tag_string)
        # print(item)
    #將每次獲得的一維數組保存進二維數組中
    item_question.append(item)
print(item_question)

方法二(推薦):還能夠用相對路徑的方法定位標籤:code

#經過觀察能夠發現,每個試題都是在一個div標籤,而且value 爲11111#1,11111#2,11111#3的標籤下的。因此咱們先將這個標籤取到,做爲一個參照。re.compile是正則表達式方法
the_tag = soup.find_all('div',value = re.compile('11111#\d'))
print(len(the_tag))
#建立二維數組,用來保存試題
item_question = []
for tag in the_tag:
    #建立一維數組,用來保存題乾和選項
    item = []
    #遍歷剛剛選好的參照標籤 
    for child_tag in tag.descendants:
        #每個參照標籤下的h6標籤都是題幹,提取出來保存。 
        if child_tag.name == "h6":
            item.append(child_tag.get_text("", strip=True))
        #每個參照標籤下的td標籤都是選項,提取出來保存
        elif child_tag.name == "td":
            if child_tag.div is not None:
                item.append(child_tag.div.get_text("", strip=True))
    item_question.append(item)
print(item_question)
相關文章
相關標籤/搜索