如何使用 beautifulsoup + 请求缩小抓取结果的范围?
How can I narrow down the results of a scrape with beautifulsoup + requests?
我的代码的功能是读取 xlxs sheet(即 whosebug.com)上的 URL 列表。
然后转到 whosebug.com 并检查主页上是否有 Instagram 帐户 link,如果有,它 return 是 link到那个并将它写在相邻的列中。
但是,某些网站会将其列在多个位置、页眉、页脚或有一个 feed 将 return 多个结果添加到单元格。
有没有办法return只有一个结果?
for cell in sheet[col][1:]:
try:
url = cell.value
r = requests.get(url)
ig_get = ['instagram.com']
ig_get_present = []
soup = BeautifulSoup(r.content, 'html5lib')
all_links = soup.find_all('a', href=True)
print(cell.value)
for ig_get in ig_get:
for link in all_links:
if ig_get in link.attrs['href']:
ig_get_present.append(link.attrs['href'])
ig_got = str(ig_get_present)
print(ig_got)
sheet.cell(cell.row, col2).value = ig_got
except requests.exceptions.ConnectionError:
pass
except requests.exceptions.TooManyRedirects:
pass
except requests.exceptions.MissingSchema:
pass
为清楚起见编辑:
有些域的社交媒体页面会有多个 link,即一个在页眉中,一个在页脚中,一个在导航栏中等,或者是其社交媒体源的镜像。在这些情况下,我在单元格中输出了多个相同的 link:
['https://instagram.com/xxx', 'https://instagram.com/xxx', 'https://instagram.com/xxx']
我只想要其中之一,而不是全部。
如果您只想将第一个匹配项输入单元格,那么您真正需要的只是在第一个匹配项之后立即放置一个 break 语句。
例如:
...
...
url = cell.value
res = requests.get(url)
domain = 'instagram.com'
urls = []
soup = BeautifulSoup(res.content, 'html5lib')
all_links = soup.find_all('a', href=True)
for link in all_links:
if domain in link['href']:
url = link['href']
urls.append(url)
sheet.cell(cell.row, col2).value = url
break
...
...
python 中的 break
语句是一个控制流语句,可立即将您从代码正在执行的任何循环中打断。
您可以在 python 文档中阅读更多相关信息 https://docs.python.org/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops
更简洁的方法是使用带有包含 (*) 运算符的 css 属性选择器,指定应该找到的域,使用 select_one 到 return 第一个仅匹配
domain = 'instagram.com'
soup.select_one(f'a[href*="{domain}"]')
除了抓取每个网站之外的另一个选择是使用 google dorks 并让 google 为您完成工作
google 笨蛋就像特定的查询,可以缩小搜索范围
由于某些网站 link 他们的 Instagram 用户名位于与主页不同的页面上,上述方法在这种情况下不起作用,但是如果您以这种格式进行 google 搜索
Site:whosebug.com intext:"https://www.instagram.com/"
google 将 return 所有在与该特定网站相关的文本中包含 https://www.instagram.com/ 的页面
我的代码的功能是读取 xlxs sheet(即 whosebug.com)上的 URL 列表。
然后转到 whosebug.com 并检查主页上是否有 Instagram 帐户 link,如果有,它 return 是 link到那个并将它写在相邻的列中。
但是,某些网站会将其列在多个位置、页眉、页脚或有一个 feed 将 return 多个结果添加到单元格。
有没有办法return只有一个结果?
for cell in sheet[col][1:]:
try:
url = cell.value
r = requests.get(url)
ig_get = ['instagram.com']
ig_get_present = []
soup = BeautifulSoup(r.content, 'html5lib')
all_links = soup.find_all('a', href=True)
print(cell.value)
for ig_get in ig_get:
for link in all_links:
if ig_get in link.attrs['href']:
ig_get_present.append(link.attrs['href'])
ig_got = str(ig_get_present)
print(ig_got)
sheet.cell(cell.row, col2).value = ig_got
except requests.exceptions.ConnectionError:
pass
except requests.exceptions.TooManyRedirects:
pass
except requests.exceptions.MissingSchema:
pass
为清楚起见编辑:
有些域的社交媒体页面会有多个 link,即一个在页眉中,一个在页脚中,一个在导航栏中等,或者是其社交媒体源的镜像。在这些情况下,我在单元格中输出了多个相同的 link:
['https://instagram.com/xxx', 'https://instagram.com/xxx', 'https://instagram.com/xxx']
我只想要其中之一,而不是全部。
如果您只想将第一个匹配项输入单元格,那么您真正需要的只是在第一个匹配项之后立即放置一个 break 语句。
例如:
...
...
url = cell.value
res = requests.get(url)
domain = 'instagram.com'
urls = []
soup = BeautifulSoup(res.content, 'html5lib')
all_links = soup.find_all('a', href=True)
for link in all_links:
if domain in link['href']:
url = link['href']
urls.append(url)
sheet.cell(cell.row, col2).value = url
break
...
...
python 中的 break
语句是一个控制流语句,可立即将您从代码正在执行的任何循环中打断。
您可以在 python 文档中阅读更多相关信息 https://docs.python.org/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops
更简洁的方法是使用带有包含 (*) 运算符的 css 属性选择器,指定应该找到的域,使用 select_one 到 return 第一个仅匹配
domain = 'instagram.com'
soup.select_one(f'a[href*="{domain}"]')
除了抓取每个网站之外的另一个选择是使用 google dorks 并让 google 为您完成工作
google 笨蛋就像特定的查询,可以缩小搜索范围
由于某些网站 link 他们的 Instagram 用户名位于与主页不同的页面上,上述方法在这种情况下不起作用,但是如果您以这种格式进行 google 搜索
Site:whosebug.com intext:"https://www.instagram.com/"
google 将 return 所有在与该特定网站相关的文本中包含 https://www.instagram.com/ 的页面