使用 BeautifulSoup 查找与特定关键字相关的链接
Posted
技术标签:
【中文标题】使用 BeautifulSoup 查找与特定关键字相关的链接【英文标题】:Using BeautifulSoup to find links related to specific keyword 【发布时间】:2019-07-22 10:06:47 【问题描述】:我必须修改这段代码,以便 scraping 只保留包含特定关键字的链接。就我而言,我正在抓取报纸页面来查找与“Brexit”一词相关的新闻。
我尝试修改 parse_links
方法,使其仅保留包含“Brexit”的链接(或“a”标签),但似乎不起作用。
我应该把条件放在哪里?
import requests
from bs4 import BeautifulSoup
from queue import Queue, Empty
from concurrent.futures import ThreadPoolExecutor
from urllib.parse import urljoin, urlparse
class MultiThreadScraper:
def __init__(self, base_url):
self.base_url = base_url
self.root_url = '://'.format(urlparse(self.base_url).scheme, urlparse(self.base_url).netloc)
self.pool = ThreadPoolExecutor(max_workers=20)
self.scraped_pages = set([])
self.to_crawl = Queue(10)
self.to_crawl.put(self.base_url)
def parse_links(self, html):
soup = BeautifulSoup(html, 'html.parser')
links = soup.find_all('a', href=True)
for link in links:
url = link['href']
if url.startswith('/') or url.startswith(self.root_url):
url = urljoin(self.root_url, url)
if url not in self.scraped_pages:
self.to_crawl.put(url)
def scrape_info(self, html):
return
def post_scrape_callback(self, res):
result = res.result()
if result and result.status_code == 200:
self.parse_links(result.text)
self.scrape_info(result.text)
def scrape_page(self, url):
try:
res = requests.get(url, timeout=(3, 30))
return res
except requests.RequestException:
return
def run_scraper(self):
while True:
try:
target_url = self.to_crawl.get(timeout=60)
if target_url not in self.scraped_pages:
print("Scraping URL: ".format(target_url))
self.scraped_pages.add(target_url)
job = self.pool.submit(self.scrape_page, target_url)
job.add_done_callback(self.post_scrape_callback)
except Empty:
return
except Exception as e:
print(e)
continue
if __name__ == '__main__':
s = MultiThreadScraper("https://elpais.com/")
s.run_scraper()
【问题讨论】:
list
的 keywords
怎么样,并检查它是否存在于锚标记的文本中?
@user5173426 我尝试检查链接中是否存在所需的单词。在检查链接中的每个链接之前,但没有得到任何结果
记得在edit 中通过sn-p 工具插入html 而不是图像。希望您的问题得到应得的支持 +
@QHarr 你是对的。谢谢
【参考方案1】:
您可以使用方法getText()
获取元素的文本并检查字符串是否实际包含“Brexit”:
if "Brexit" in link.getText().split():
url = link["href"]
【讨论】:
【参考方案2】:你需要导入re
模块来获取具体的文本值。试试下面的代码。
import re
links = soup.find_all('a', text=re.compile("Brexit"))
这应该返回仅包含英国退欧的链接。
【讨论】:
@Kajal,我只是好奇,如果文本中的“brexit”全部小写,这是否也有效?换句话说,使用re.compile("Brexit")
会区分大小写吗?
re.compile() 区分大小写。但是你可以在 re.compile() 中添加 re.IGNORECASE。
@chitown88 您可以将 re.IGNORECASE 传递给搜索匹配或子的标志参数。 ***.com/questions/500864/…
哦,太好了。我必须记住这一点。感谢 Kajal 和 Carlos,这对我将来很有用。
您可以使用 range(len(links))
并循环遍历它,并在达到 20 时使用 break
检查从循环中跳出。【参考方案3】:
我在这个函数中添加了一个检查。看看这是否对你有用:
def parse_links(self, html):
soup = BeautifulSoup(html, 'html.parser')
links = soup.find_all('a', href=True)
for link in links:
if 'BREXIT' in link.text.upper(): #<------ new if statement
url = link['href']
if url.startswith('/') or url.startswith(self.root_url):
url = urljoin(self.root_url, url)
if url not in self.scraped_pages:
self.to_crawl.put(url)
【讨论】:
以上是关于使用 BeautifulSoup 查找与特定关键字相关的链接的主要内容,如果未能解决你的问题,请参考以下文章
使用 BeautifulSoup 查找具有两种特定样式的标签
使用 BeautifulSoup 查找包含特定文本的 HTML 标签
BeautifulSoup/Regex:从 href 中查找特定值