AttributeError:“ NoneType”对象在Regex

时间:2019-01-15 04:57:14

标签: python regex web-scraping beautifulsoup

我写了一个正则表达式来从网页上抓取数据。但是,我得到提到的错误。我无法找到解决方案。 有人建议

try:
    code
except:
     Attribute error

原始代码:

import urllib.request
import bs4
import re

url ='https://ipinfo.io/AS7018'
def url_to_soup(url):
    req = urllib.request.Request(url)
    opener = urllib.request.build_opener()
    html = opener.open(req)
    soup = bs4.BeautifulSoup(html, "html.parser")
    return soup


s = str(url_to_soup(url))
#print(s)
asn_code, name = re.search(r'<h3 class="font-semibold m-0 t-xs-24">(?P<ASN_CODE>AS\d+) (?P<NAME>[\w.\s]+)</h3>', s)\
        .groups() # Error code
print(asn_code)
""" This is where the error : From above code """
country = re.search(r'.*href="/countries.*">(?P<COUNTRY>.*)?</a>',s).group("COUNTRY")
print(country)
registry = re.search(r'Registry.*?pb-md-1">(?P<REGISTRY>.*?)</p>',s, re.S).group("REGISTRY").strip()
print(registry)
# flag re.S make the '.' special character match any character at all, including a newline;
ip = re.search(r'IP Addresses.*?pb-md-1">(?P<IP>.*?)</p>',s, re.S).group("IP").strip()
print(ip)

2 个答案:

答案 0 :(得分:1)

声明:

re.search(r'<h3 class="font-semibold m-0 t-xs-24">(?P<ASN_CODE>AS\d+) (?P<NAME>[\w.\s]+)</h3>', s)

正在返回None并在字符串s中找不到所需的模式。

根据re.search的文档

  

扫描字符串以查找正则表达式模式产生匹配项的第一个位置,然后返回相应的MatchObject实例。如果字符串中没有位置与模式匹配,则返回;请注意,这不同于在字符串中的某个位置找到零长度匹配项。

您必须重新设计正则表达式或调试代码,才能在使用上述模式时找出s包含的内容。

答案 1 :(得分:1)

re.search在找不到任何内容时返回NoneNone不响应方法.groups()。在详细检查匹配项之前,请检查是否存在匹配项。

match = re.search(r'<h3 class="font-semibold m-0 t-xs-24">(?P<ASN_CODE>AS\d+) (?P<NAME>[\w.\s]+)</h3>', s)
if match:
    asn_code, name = match.groups()

但是,既然您使用的是Beautiful Soup,为什么要先进行字符串化然后再进行正则表达式匹配?就像买一包速溶汤,将粉加到水中,煮沸,然后将其脱水成粉。为什么还要使用BeautifulSoup?

soup.select('h3.font-semibold.m-0.t-xs-24')[0].content

将为您提供该<h3>元素的内容;然后根据需要在那个上应用正则表达式。通过HTML文档进行正则表达式为generally a bad idea

编辑:究竟是什么TypeError给您?这是典型的XY problem,您在其中解决错误的问题。我验证了此方法是否可以正常运行,没有TypeError(Python 3):

ast_re = re.compile(r'(?P<ASN_CODE>AS\d+) (?P<NAME>[\w.\s]+)')
soup = url_to_soup(url)
ast_h3 = next(
    (m for m in (ast_re.match(h3.text) for h3 in soup.select('h3')) if m),
    None)
if ast_h3:
    asn_code, name = asn_h3.groups()