用美丽的汤解析HTML

时间:2014-03-09 19:35:49

标签: python parsing web-scraping beautifulsoup

我有一个元组定义了我对给定页面感兴趣的链接关键字,所以:

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 个答案:

答案 0 :(得分:2)

每当您发现自己手动迭代标记以进行其他过滤时,通常最好只使用bs4 API。在这种情况下,您可以将正则表达式传递给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'标签(???)所以a循环执行更多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 &amp; 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 &amp; World</a>,
 <a href="/vector__designs-desktop-wallpapers.html">Vector &amp; Designs</a>]