zoukankan      html  css  js  c++  java
  • Beautifulsoup 爬取页面试题

    假设有一个页面,页面中有n道选择题,每道选择题有若干个选项。题干部分用h6 标签标记。选项部分用的是td 下的div 标签。如下图所示:

    整个页面是将如下的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 库中的方法将页面上的题目和选项提取出来。

    首先要引入需要用到的包:

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

    然后可以用多种方法提取页面源码,:

    #既可以打开一个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 对象。接下来只要根据对象的标签结构,通过一定方法定位到目标标签,就可以了。

    方法一:下面这种方法比较基本,用的是“绝对路径”找寻标签

    # 通过观察发现,题干部分全部都是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)

    方法二(推荐):还可以用相对路径的方法定位标签:

    #通过观察可以发现,每一个试题都是在一个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)
  • 相关阅读:
    C#编程(四十一)----------用户定义的数据类型转换
    C#编程(四十)----------运算符重载
    C#编程(三十九)----------比较对象的相等性
    下载mqtt.fx
    python3 mqtt 客户端以及服务端
    mac 下使用nasm
    shell equal
    python client.py
    常见面试题
    mysql 包含查找
  • 原文地址:https://www.cnblogs.com/testertry/p/11516536.html
Copyright © 2011-2022 走看看