使用正则表达式改善html代码中的过滤器链接

时间:2018-10-02 19:32:39

标签: python regex

我的项目的目的是web scrap一个搜索引擎(我选择了DuckDuckGo)。要获取第一页上的所有链接,然后输入这些链接中的每个链接,请获取HTML源代码并执行一个正则表达式,该过滤器将过滤HTML代码中的所有.onion网站。 / p>

我将从这里开始假设我们已经在网上刮了搜索引擎,并将所有网站都放在了第一页(我在DuckDuckGo上的搜索字词是:暗网“ .onion”)

这是代码的运行方式(我将在代码comments中详细说明):

import requests
from bs4 import BeautifulSoup
import urllib.parse
import re

html_data=[] 

#This will be the list that will contains the HTML code of 
#each website I visit. For example, html_data[0]
#will contain all the html source code of the first website,
#html_data[1] of the second website and so on.

for x in links: #links is the list that contains all the websites that I got from web scraping DuckDuckGo.
    data = requests.get(str(x))
    html_data.append(data.text)

#Now html_data contains all the html source code of all the websites in links

print("")
print("============================ONIONS================================")
print("")


#Here I pass a regex to filter all the content in each case of the list (so that I get only .onion links)

for x in html_data:
    for m in re.finditer(r'(?:https?://)?(?:www)?(\S*?\.onion)\b', x, re.M | re.IGNORECASE):
        print(m.group(0))

所以我的代码运行正常。但是,有一个简单的问题。正则表达式不能正确过滤所有内容。我的.onion网站上嵌套了一些HTML代码。而且,我经常在输出中得到.onion

以下是输出示例:

href="http://jv7aqstbyhd5hqki.onion
class="external_link">http://jv7aqstbyhd5hqki.onion
href="http://xdagknwjc7aaytzh.onion
data-qt-tooltip="xdagknwjc7aaytzh.onion
">http://xdagknwjc7aaytzh.onion
href="http://sbforumaz7v3v6my.onion
class="external_link">http://sbforumaz7v3v6my.onion
href="http://kpmp444tubeirwan.onion
class="external_link">http://kpmp444tubeirwan.onion
href="http://r5c2ch4h5rogigqi.onion
class="external_link">http://r5c2ch4h5rogigqi.onion
href="http://hbjw7wjeoltskhol.onion
class="external_link">http://hbjw7wjeoltskhol.onion
href="http://khqtqnhwvd476kez.onion
class="external_link">http://khqtqnhwvd476kez.onion
href="http://jahfuffnfmytotlv.onion
class="external_link">http://jahfuffnfmytotlv.onion
href="http://ocu3errhpxppmwpr.onion
class="external_link">http://ocu3errhpxppmwpr.onion
href="http://germanyhusicaysx.onion
data-qt-tooltip="germanyhusicaysx.onion
">http://germanyhusicaysx.onion
href="http://qm3monarchzifkwa.onion
class="external_link">http://qm3monarchzifkwa.onion
href="http://qm3monarchzifkwa.onion
class="external_link">http://qm3monarchzifkwa.onion
href="http://spofoh4ucwlc7zr6.onion
data-qt-tooltip="spofoh4ucwlc7zr6.onion
">http://spofoh4ucwlc7zr6.onion
href="http://nifgk5szbodg7qbo.onion
class="external_link">http://nifgk5szbodg7qbo.onion
href="http://t4is3dhdc2jd4yhw.onion
class="external_link">http://t4is3dhdc2jd4yhw.onion

我想知道如何改进此regex,以便以正确的格式获取.onion链接。

2 个答案:

答案 0 :(得分:2)

您可以使用此正则表达式。它与 .onion
的URL匹配 它适用于源html,获取/测试任何标签的href属性。

您不需要使用正则表达式选项,因为它们是内联的。
您想要的是在 Capture group 3 中。

r"(?si)<[\w:]+(?=(?:[^>\"']|\"[^\"]*\"|'[^']*')*?(?<=\s)href\s*=\s*(?:(['\"])\s*(((?!mailto:)(?:(?:https?|ftp)://)?(?:(?:(?!\1)\S)+(?::(?:(?!\1)\S)*)?@)?(?:(?:[a-z\u00a1-\uffff0-9]-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-?)*[a-z\u00a1-\uffff0-9]+)*?\.onion\b)(?:(?!\1).)*?)\s*\1))\s+(?:\".*?\"|'.*?'|[^>]*?)+>"

https://regex101.com/r/oeYCxX/1

可读版本

 (?si)                         # Dot-all and case insensitive modifiers
 < [\w:]+                      # Any tag
 (?=
      (?: [^>"'] | " [^"]* " | ' [^']* ' )*?
      (?<= \s )
      href \s* = \s*                # href attribute
      (?:
           ( ['"] )                      # (1)
           \s* 
           (                             # (2 start), Full url
                (                             # (3 start), The url up to '.onion'
                     (?! mailto: )
                     (?:
                          (?: https? | ftp )
                          ://
                     )?
                     (?:
                          (?:
                               (?! \1 )
                               \S 
                          )+
                          (?:
                               : 
                               (?:
                                    (?! \1 )
                                    \S 
                               )*
                          )?
                          @
                     )?
                     (?:
                          (?: [a-z\u00a1-\uffff0-9] -? )*
                          [a-z\u00a1-\uffff0-9]+ 
                     )
                     (?:
                          \.
                          (?: [a-z\u00a1-\uffff0-9] -? )*
                          [a-z\u00a1-\uffff0-9]+ 
                     )*?
                     \.onion                        \b 
                )                             # (3 end)
                (?:                           # Parameters
                     (?! \1 )
                     . 
                )*?
           )                             # (2 end)
           \s* \1 
      )
 )
 \s+ 
 (?: " .*? " | ' .*? ' | [^>]*? )+
 >

答案 1 :(得分:0)

\S*?过于宽松,无法进行网址匹配。它将匹配尽可能少的非空白字符以满足模式,其中包括<>之类的内容。

要了解URL中哪些字符有效,请参见以下答案:Which characters make a URL invalid?

您也许可以摆脱[^\s<>]之类的\S之类的束缚。 [^\s<>]将匹配非空格或大括号的任何字符,而不匹配非空格的任何字符。