如何区分<a>有无href in BeautifulSoup?

How to make a distinction between <a> with & without href in BeautifulSoup?

我正在抓取一个网站,目标是广告 ID,我正在抓取一个标签,然后 ['href'],但是一些标签没有 href,并且 return 一个错误。

如何区分这两者? 代码:

def id_finder(url):
    id_list = []
    r = requests.get(url)
    soup = BeautifulSoup(r.text, 'html.parser')
    ads_ids = soup.find_all('a')
    for ID in ads_ids:
        link = ID['href']
        if link.find('/car-search/'):
            pass
        else:
            print(link)

           
def main():
    driver = webdriver.Chrome(r"./chromedriver")
    driver.get("https://iranpelak.com/car-search")
    driver.maximize_window()
    time.sleep(2)
    try:
        WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//button[@data-role='end']"))).click()
    except Exception as e:
        print(e)
        pass
    first_page_url = driver.current_url
    for page in range(1, 10000):
        if page == 1:
            id_finder(first_page_url)
        else:
            pass

我得到的错误:

return self.attrs[key]
KeyError: 'href'

我认为这是因为某些 a 标签没有 href,但是您的意见将不胜感激!

您可以添加一个 try/except 块来处理那些不包含 href 元素的标签,捕获抛出的 KeyError

for ID in ads_ids:
    try:
        link = ID['href']
    except KeyError:
        # Handle cases here
    if link.find('/car-search/'):
        pass
    else:
        print(link)

如果你不需要在这里处理任何东西,你可以简单地使用continue跳到循环中的下一个迭代。

您问题的确切答案是 you can pass custom function (filter)soup.find_all() 方法:

spam = """
<a href="some url">a tag with href</a>
<a>a tag without href</a>
"""

soup = BeautifulSoup(spam, 'html.parser')

# find all a tags 
a_tags = soup.find_all('a')
for tag in a_tags:
    print(tag.text)

# find only a tags with href
a_tags = soup.find_all(lambda tag: tag.name == 'a' and tag.get('href'))
for tag in a_tags:
    print(tag.text)
    print(tag['href']) # or print(tag.get('href'))

输出

a tag with href
a tag without href
a tag with href
some url

但是,如评论中所述,可以使用 tag.get() 方法或处理 KeyError 异常

a_tags = soup.find_all('a')
for tag in a_tags:
    link = tag.get('href')
    if link:
        print(link)


a_tags = soup.find_all('a')
for tag in a_tags:
    try:
        link = tag['href']
        print(link)
    except KeyError:
        pass

输出

some url
some url

你可以压缩这个:

a_tags = soup.find_all('a')

for ID in ads_ids:
    link = ID['href']
    if link.find('/car-search/'):
        pass
    else:
        print(link)

进入这个:

print([i['href'] for i in soup.select('a[href]:not([href*="/car-search/"])')])

a[href] -> a 标签仅具有 href 属性;

:not([href*="/car-search/"]) -> hrefs 不包含字符串 /car-search/

组合它们指定 a 标签仅具有 href 属性,不包含指定的字符串。

此 css 选择器列表通过 select() 方法应用,返回一个列表,该列表可以从列表推导中的每个成员中提取 href 属性。提取的 href 列表包含在 print() 调用中。