最新消息:20210917 已从crifan.com换到crifan.org

【已解决】BeautifulSoup中只搜索当前直接子节点不搜索其他子孙节点

BeautifulSoup crifan 406浏览 0评论
折腾:
【未解决】Python同步印象笔记帖子到WordPress后丢失缩进
期间,对于Evernote的html:
<en-note>
  <ul>
    <li>
      <div>sudo pmset -b GPUSwitch 0</div>
    </li>
    <ul>
      <li>
        <div>-b 表示 battery 为电池模式</div>
      </li>
      <ul>
        <li>
          <div>电池模式时:用过0 集成显卡 integrated graphics</div>
        </li>
      </ul>
    </ul>
    <li>
      <div>sudo pmset -c GPUSwitch 1</div>
    </li>
    <ul>
      <li>
        <div>-c 表示 charger 为电源模式</div>
      </li>
      <ul>
        <li>
          <div>电源模式时:用1=独立显卡 high performance graphic cards</div>
        </li>
      </ul>
    </ul>
  </ul>
</en-note>
想要只搜索 en-note当前的直接子节点中的ul
而不想要搜索所有子孙节点中的的ul
去找官网文档,找到了:
recursive 参数
去试试:
    ulSoupList = soup.find("ul", recursive=False)
结果:
对于调试输出的Evernote的html:
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">
<en-note>
  <div>折腾:</div>
。。。
  <div>是对的</div>
  <ul>
    <li>
      <div>0 为集成显卡</div>
    </li>
    <li>
      <div>1 为独立显卡</div>
    </li>
    <li>
      <div>2 为自动切换</div>
    </li>
  </ul>
  <div><br /></div>
。。。
  <div>也可以根据情况设置模式</div>
  <ul>
    <li>
      <div>sudo pmset -b GPUSwitch 0</div>
    </li>
    <ul>
      <li>
        <div>-b 表示 battery 为电池模式</div>
      </li>
      <ul>
        <li>
          <div>电池模式时:用过0 集成显卡 integrated graphics</div>
        </li>
      </ul>
    </ul>
    <li>
      <div>sudo pmset -c GPUSwitch 1</div>
    </li>
    <ul>
      <li>
        <div>-c 表示 charger 为电源模式</div>
      </li>
      <ul>
        <li>
          <div>电源模式时:用1=独立显卡 high performance graphic cards</div>
        </li>
      </ul>
    </ul>
  </ul>
  <div><br /></div>
。。。
  <div>其中N:</div>
  <ul>
    <li>
      <div>0 = 集成显卡</div>
    </li>
    <ul>
      <li>
        <div>sudo pmset -a GPUSwitch 0</div>
      </li>
    </ul>
    <li>
      <div>1 = 独立显卡</div>
    </li>
    <ul>
      <li>
        <div>sudo pmset -a GPUSwitch 1</div>
      </li>
    </ul>
    <li>
      <div>2 = 自动切换</div>
    </li>
    <ul>
      <li>
        <div>sudo pmset -a GPUSwitch 2</div>
      </li>
    </ul>
  </ul>
  <div><br /></div>
  <div>更高级的用法,也可以根据电源模式设置不同GPU模式,比如:</div>
  <ul>
    <li>
      <div>sudo pmset -b GPUSwitch 0</div>
    </li>
    <ul>
      <li>
        <div>-b = battery =电池模式</div>
      </li>
      <ul>
        <li>
          <div>电池模式 用 0 集成显卡 integrated graphics</div>
        </li>
      </ul>
    </ul>
    <li>
      <div>sudo pmset -c GPUSwitch 1</div>
    </li>
    <ul>
      <li>
        <div>-c = charger = 电源模式</div>
      </li>
      <ul>
        <li>
          <div>电源模式 用 1 独立显卡 high performance graphic cards</div>
        </li>
      </ul>
    </ul>
  </ul>
  <div><br /></div>
</en-note>
再去加上调试对比代码:
    noteHtml = curNote.content
    soup = utils.htmlToSoup(noteHtml)


    enNoteSoup = soup.find("en-note")


    allSubUlSoupList = enNoteSoup.find_all("ul")
    allSubUlSoupNum = len(allSubUlSoupList)
    logging.info("Found %d all sub level ul list", allSubUlSoupNum)
可以找到所有的15个:
    directUlSoupList = enNoteSoup.find_all("ul", recursive=False)
    directUlSoupNum = len(directUlSoupList)
    logging.info("Found %d top level ul list", directUlSoupNum)
正是我们希望的,只可以找到直属的4个:
即可。
【总结】
对于这种html
<html>
    <ul>
        <li>
            <ul> xxx </ul>
        </li>
    </ul>
    <ul>xxx</ul>
</html>
如果要找到所有的ul节点:3个
则用:
soup.find_all("ul")
如果只想找到最顶层的ul:2个
则用:
soup.find_all("ul", recursive=False)
即可。
【后记20201229】
发现此处的html:
<html>
 <div>
  <span style="font-size: unset; color: unset; font-family: unset; --inversion-type-color: simple;">
   折腾:
  </span>
 </div>
。。。
 <div>
  即使你正确安装了Charles的SSL证书(不论是电脑端还是手机端),结果安卓app中,部分的https的包,还是加密的,无法看到明文,其实现方式就是:
 </div>
 <ul>
  <li>
   <div>
    ssl pinning
   </div>
  </li>
  <ul>
   <li>
    <div>
     =Certificate pinning
    </div>
   </li>
   <li>
    <div>
。。。
 <ul>
  <li>
   <div>
    不仅要确认是否合法有效的host主机名
   </div>
  </li>
  <li>
   <div>
    还要确认是否合法有效的根证书Root CA
   </div>
  </li>
  <ul>
   <li>
    <div>
     此处app只认自己的证书,不认Charles的证书
    </div>
   </li>
   <li>
    <div>
     所以Charles就无法抓这种带SSL Pinning的https的包了
    </div>
   </li>
  </ul>
 </ul>
等,明显有ul的list的情况下,代码:
    topUlSoupList = soup.find_all("ul", recursive=False)
    topOlSoupList = soup.find_all("ol", recursive=False)
竟然搜索不到,都是空:
但是用代码:
soup.find_all("ul")
却是可以搜出来结果的:
然后去调试:
输出当前html:
utils.dbgSaveHtml(soup.prettify())
查了下,发现原因是:
此处返回的html是:
<html>
xxx
</html>
导致:
最顶层top,只有html节点,没有ol节点
所以去改为,html转soup时,去掉此处顶层html,变成:
<div>xxx</div>
。。。
<ul>
 xxx
</ul>
。。。
估计就可以了。
代码改为:
EvernoteToWordpress.py
    # soup = crifanEvernote.noteContentToSoup(curNote)
    # Note: makesure removed top html, then following can search out ul and ul list with recursive=False
    soup = crifanEvernote.noteContentToSoup(curNote, isKeepTopHtml=False)
和:
libs/crifan/crifanEvernote.py
    def noteContentToSoup(curNote, isKeepTopHtml=True):
        """Convert Evernote Note content to BeautifulSoup Soup


        Args:
            curNote (Note): Evernote Note
            isKeepTopHtml (bookl): whether keep top html. Ture to <html>xxx<html>, False to xxx
        Returns:
            Soup
        Raises:
        """
        noteHtml = crifanEvernote.getNoteContentHtml(curNote, isKeepTopHtml)
。。。
结果:
就可以了搜到顶层的ul和ol了。
然后后续继续处理即可。

转载请注明:在路上 » 【已解决】BeautifulSoup中只搜索当前直接子节点不搜索其他子孙节点

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
93 queries in 0.199 seconds, using 23.35MB memory