用Beautiful Soup解析HTML
我有一个元组,里面定义了我感兴趣的链接关键词,具体如下:
categories = ('car', 'planes', ...)
我想把某个特定类里面的所有链接放到一个列表里,这些链接的内容要和我元组里的任意一个值匹配。文档内容如下:
<div class='content'>
<ul class='side-panel'>
<li><a href='page1.html'>page 1</a></li>
<li><a href='page2.html'>page 2</a></li>
<li><a href='best_car_2013.html'>Best Cars</a></li>
...
</ul>
</div>
目前我在做的是:
found = []
for link in soup.find_all(class_='side-panel'):
for category in categories:
if re.search(category, link.get('href')):
found.append(link)
但是我遇到了一个类型错误,提示“期望是字符串或缓冲区”。在调试脚本时,我发现我获取到了所有的 'li' 标签以及它们对应的锚点标签,但我在遍历这些结果时遇到了麻烦,无法从中提取出每个链接的 'href' 属性,并把它们放到列表里。
1 个回答
2
每当你需要手动遍历标签来进行额外的筛选时,其实直接使用 bs4
的接口会更好。在这种情况下,你可以把正则表达式传给 find_all
方法。
soup.find(class_='side-panel').find_all(href=re.compile('|'.join(categories)))
Out[86]: [<a href="best_car_2013.html">Best Cars</a>]
如果不太明白,把 categories
用管道符连接成一个表达式,可以让 re
引擎判断是否有 任何 类别与 href 属性匹配。这样就不需要逐个遍历每个类别并单独进行 re
搜索了。
编辑:(提到评论中的链接)看起来你抓取的页面有 两个 class='side-panel categories'
标签(???),所以在最初的 find_all
操作后再进行更多的 find_all
操作可能是合适的:
[t for tags in soup.find_all(class_='side-panel categories')
for t in tags.find_all(href=re.compile('|'.join(selected_links)))]
Out[24]:
[<a href="/animals__birds-desktop-wallpapers.html">Animals & Birds</a>,
<a href="/beach-desktop-wallpapers.html">Beach</a>,
<a href="/bikes__motorcycles-desktop-wallpapers.html">Bikes</a>,
<a href="/cars-desktop-wallpapers.html">Cars</a>,
<a href="/digital_universe-desktop-wallpapers.html">Digital Universe</a>,
<a href="/flowers-desktop-wallpapers.html">Flowers</a>,
<a href="/nature__landscape-desktop-wallpapers.html">Nature</a>,
<a href="/planes-desktop-wallpapers.html">Planes</a>,
<a href="/travel__world-desktop-wallpapers.html">Travel & World</a>,
<a href="/vector__designs-desktop-wallpapers.html">Vector & Designs</a>]