无法从网页的不同深度刮出类似的链接

2024-04-26 09:25:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我用python创建了一个脚本来解析网页中的不同链接。登录页中有两个部分。一个是Top Experiences,另一个是More Experiences。我当前的尝试可以从这两个类别中获取链接。你知道吗

我想收集的链接类型(很少)在Top Experiences部分下面。但是,当我遍历More Experiences节下的链接时,我可以看到它们都指向一个页面,其中有一个名为Experiences的节,在该节下有与登录页Top Experiences下的链接类似的链接。我要把它们都抓起来。你知道吗

我想要的一个这样的链接是:https://www.airbnb.com/experiences/20712?source=seo。你知道吗

website link

我当前的尝试从两个类别获取链接:

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

URL = "https://www.airbnb.com/sitemaps/v2/experiences_pdp-L0-0"

def get_links(link):
    res = requests.get(link)
    soup = BeautifulSoup(res.text,"lxml")
    items = [urljoin(link,item.get("href")) for item in soup.select("div[style='margin-top:16px'] a._1f0v6pq")]
    return items

if __name__ == '__main__':
    for item in get_links(URL):
        print(item)

How can I parse all the links under Top Experiences section along with the links under Experiences section that can be found upon traversing the links under More Experiences?

如果有任何不清楚的地方,请check out the image。我用了一支油漆笔,所以写起来可能有点难理解。


Tags: thehttpsimportget链接topmorewww
3条回答

似乎“顶级体验”和“更多体验”链接共享同一类,因此您可以使用.find_all来获取链接。你知道吗

import requests
#from urllib.parse import urljoin
from bs4 import BeautifulSoup

# URL to scrape
url = "https://www.airbnb.com/sitemaps/v2/experiences_pdp-L0-0"

# Make request and Initialize BS4 with request content
req = requests.get(url)
soup = BeautifulSoup(req.content, "lxml")

# Tag that contains "Top Experiences" and "More Experiences"
soup.find_all(class_="_l8g1fr")

# Test Code
#Prints title of links and the href
links = soup.find_all(class_="_l8g1fr")
for link in links:
    print(link.find("a").get_text())
    print(link.find("a").get('href'))

重构代码以满足您的编码范式。你知道吗

过程:

  1. 获取所有Top Experiences链接

  2. 获取所有More Experiences链接

  3. 向所有More Experiences链接逐个发送请求,并获取每个页面Experiences下的链接。

链接所在的div是相同的,因为所有页面都具有相同的类_12kw8n71

import requests
from urllib.parse import urljoin
from bs4 import BeautifulSoup
from time import sleep
from random import randint
URL = "https://www.airbnb.com/sitemaps/v2/experiences_pdp-L0-0"
res = requests.get(URL)
soup = BeautifulSoup(res.text,"lxml")
top_experiences= [urljoin(URL,item.get("href")) for item in soup.find_all("div",class_="_12kw8n71")[0].find_all('a')]
more_experiences= [urljoin(URL,item.get("href")) for item in soup.find_all("div",class_="_12kw8n71")[1].find_all('a')]
generated_experiences=[]
#visit each link in more_experiences
for url in more_experiences:
    sleep(randint(1,10))#avoid blocking by putting some delay
    generated_experiences.extend([urljoin(URL,item.get("href")) for item in soup.find_all("div",class_="_12kw8n71")[0].find_all('a')])

注意事项:

  1. 您所需的链接将出现在三个列表中top_experiencesmore_experiencesgenerated_experiences

  2. 我添加了随机延迟以避免被阻塞。

  3. 不要打印列表,因为它太长了。你知道吗

    top_experiences-50个链接

    more_experiences-299链接

    generated_experiences-14950个链接

解决方法有点棘手。它可以通过几种方式实现。我发现最有用的是递归地使用More Experiences函数中get_links()下的链接。More Experiences下的所有链接都有一个公共关键字_pdp-。你知道吗

因此,当您在函数中定义conditional语句以使链接递归地通过函数get_links()进行筛选时,else块将生成所需的链接。最需要注意的是,所有需要的链接都在类_1f0v6pq中,因此获取链接的逻辑相当简单。你知道吗

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

URL = "https://www.airbnb.com/sitemaps/v2/experiences_pdp-L0-0"

def get_links(link):
    res = requests.get(link)
    soup = BeautifulSoup(res.text,"lxml")
    for item in soup.select("div[style='margin-top:16px'] a._1f0v6pq"):
        if "_pdp-" in item.get("href"):
            get_links(urljoin(URL,item.get("href")))
        else:
            print(urljoin(URL,item.get("href")))

if __name__ == '__main__':
    get_links(URL)

相关问题 更多 >