假設有一個頁面,頁面中有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> 選一二三仍是四五六呢。</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)