如何在 Python 中使用 Regex 从 HTML <a> 标签中提取 Facebook 页面 URL?

Posted

技术标签:

【中文标题】如何在 Python 中使用 Regex 从 HTML <a> 标签中提取 Facebook 页面 URL?【英文标题】:How to extract Facebook page URL from HTML <a> tag using Regex in Python? 【发布时间】:2019-09-14 17:54:19 【问题描述】:

我正在抓取一些网站以使用 Beautiful Soup 在 Python 3 中提取 Facebook 页面 URL。我有兴趣为每个网站只提取一个 URL,并重定向到 Facebook 页面配置文件,这不是共享类型的。

出于这个原因,我尝试使用正则表达式从&lt;a&gt; 标记中的href 属性中提取URL。使用 Beautiful Soup,我为每个网站提取了第一个 &lt;a&gt; 标记,按包含 Facebook 页面 URL 的 href 属性的值进行过滤。

我的代码如下:

# coding=utf-8
from bs4 import BeautifulSoup
import requests
import re


def makeSoup(website):
    if 'http' in website:
        page = requests.get(website)
    else:
        page = requests.get('http://' + website)
    soup = BeautifulSoup(page.content, 'html.parser')
    page.close()
    return soup


def facebookProfileScraper(soup):
    link = soup.find('a', 'href': re.compile("https?://(www\\.)?facebook\\.com/[^(share)]?(\\w+\\.?)+"))
    if link is None:
        return "NaN"
    return link['href'] 

我想从中提取 URL 的 &lt;a&gt; 标记的示例如下(我用数字来标识每个网站也用于我的尝试结果):

1. <a class="rss fb" href="http://www.facebook.com/gironafc" target="_blank">Facebook</a>
2. <a href="https://www.facebook.com/waterworld.parcaquatic" target="_blank"><i class="fa fa-facebook"></i></a>
3. <a class="social facebook" target="_blank" href="https://www.facebook.com/aquabrava"><span class="fa fa-facebook"></span></a>
4. <a href="https://www.facebook.com/UEO1921" target="_blank"><img   src="http://www.ueolot.com/wp-content/themes/realsoccer/images/light/social-icon/facebook.png" />
</a>
5. <a href="https://www.facebook.com/Roc%C3%B2drom-Girona-187271461378780/">Facebook</a>
6. <a class="fb_share" href="https://www.facebook.com/pages/Skydive-Empuriabrava/44214266003?fref=ts" target="_blank"></a>

第一次尝试

https?://(www\\.)?facebook\\.com/[^(share)]?(\\w+\\.?)+

但我得到了这些&lt;/a&gt; 标签:

1. <a href="http://facebook.com/share.php?src=bm&amp;v=3&amp;u=" target="_blank"><span class="fa fa-facebook"></span></a>
2. <a href="https://www.facebook.com/waterworld.parcaquatic" target="_blank"><i class="fa fa-facebook"></i></a>
3. <a class="social facebook" href="https://www.facebook.com/aquabrava" target="_blank"><span class="fa fa-facebook"></span></a>
4. <a href="https://www.facebook.com/UEO1921" target="_blank"><img   src="http://www.ueolot.com/wp-content/themes/realsoccer/images/light/social-icon/facebook.png" />
</a>
5. <a href="https://www.facebook.com/Roc%C3%B2drom-Girona-187271461378780/">Facebook</a>
6. <a class="fb_share" href="https://www.facebook.com/pages/Skydive-Empuriabrava/44214266003?fref=ts" target="_blank"></a>

来自网站 1。我得到了错误的 &lt;a&gt; 标签。

第二次尝试

https?://(www\\.)?facebook\\.com/[^(share)](\\w+\\.?)+

我尝试在[^share] 之后删除?,但我得到了以下标签:

1. <a class="rss fb" href="http://www.facebook.com/gironafc" target="_blank">Facebook</a>
2. <a href="https://www.facebook.com/waterworld.parcaquatic" target="_blank"><i class="fa fa-facebook"></i></a>
3. None
4. <a href="https://www.facebook.com/UEO1921" target="_blank"><img   src="http://www.ueolot.com/wp-content/themes/realsoccer/images/light/social-icon/facebook.png" />
</a>
5. <a href="https://www.facebook.com/Roc%C3%B2drom-Girona-187271461378780/">Facebook</a>
6.<a class="fb_share" href="https://www.facebook.com/pages/Skydive-Empuriabrava/44214266003?fref=ts" target="_blank"></a>

从网站 3. 我不提取任何 &lt;a&gt; 标签,因为 [^(share)] 我用 a 否定任何网址(或 shhe 中的任何一个) 在http://www.facebook.com/ 之后。

第三次尝试

https?://(www\\.)?facebook\\.com/(\\w+\\.?)+

我尝试删除 [^share],但我得到的标签与第一次尝试相同,因此也获得了共享类型 URL。

如何仅选择没有共享类型 Facebook URL 的 a 标签作为 href 值?

【问题讨论】:

所以你想从没有分享的 Facebook 页面中提取 url 对吗? 没错!我编辑了文本,使其更清晰 【参考方案1】:
def foo(url):
    l = []
    soup = BeautifulSoup(requests.get(url).text, "html.parser")
    links = soup.find_all("a")
    for link in links:
        if not "share" in link.get("href").lower():
            l.append(link)
    return l

此函数检查链接中的share 并返回没有share 的链接。

【讨论】:

谢谢!该解决方案有效,但我希望正则表达式的解决方案具有更好的代码性能:)【参考方案2】:

我通过改进正则表达式找到了解决方案。 This 问题对我帮助很大。 这是我的案例的正则表达式:

https?://(www\.)?facebook\.com/(?!share\.php).(\S+\.?)+

它将所有&lt;a&gt;标签与Facebook页面URL匹配为href值。

使用正则表达式(?!anywordorexpression).,将不会提取任何包含anywordorexpression 子字符串的字符串。

【讨论】:

【参考方案3】:

您可以使用更高效的 css 属性选择器,使用 bs4 4.7.1 和 :not 和 * 包含运算符

links = [item['href'] for item in soup.select("[href^='https://www.facebook.com/']:not([href*='share'])")]

仅适用于第一个链接

link = soup.select_one("[href^='https://www.facebook.com/']:not([href*='share'])")['href']

【讨论】:

以上是关于如何在 Python 中使用 Regex 从 HTML <a> 标签中提取 Facebook 页面 URL?的主要内容,如果未能解决你的问题,请参考以下文章

Python 3 regex 如何正确使用分组?

在 HTML 单元格中使用 HTML 解析 Python 正则表达式 [重复]

使用python regex从字符串中提取单词

如何将 JSON 中的值替换为 RegEx 在使用 Python 的文件中找到的值?

如何使用 Regex.Replace 从字符串中删除数字?

如何剪切部分文本并用Python和RegEx替换每一行