首页 > 解决方案 > 通过使用请求的循环从多个/动态页面(可通过基本 url 和查询参数访问)获取/抓取数据

问题描述

所以我一直在尝试从网站上抓取一些数据作为练习来磨练我的 Python 技能。该页面包含一个包含公司详细信息的卡片列表(似乎每页 50 个)和下面的导航,指向基本 url + 页码参数,如https://clutch.co/uk/app-developers?page=3

我被困在一个点,如果我为每个 url(基本 url + 页码参数)创建新请求并使用多个(发布)请求获取数据,则数据被正确获取(new data for each url just as I wanted),但是当我将这些步骤放在循环中时,(generating the url through for loop and params)我得到仅来自第一页的结果(尽管结果会重复循环中指定的时间)。

这是我尝试过的两种不同结果的代码:

#Base code for the project 

import requests
from bs4 import BeautifulSoup as bs

base_url = 'https://clutch.co/uk/app-developers?page='
urls = [base_url + str(x) for x in range(0, 21)]
s = requests.Session()

#Function to extract link href from each element in bs4 object
def get_profile_link(profile_links, profiles=[]):
    for link in profile_links:
        profiles.append(link['href'])
    return profiles

方法 1:这有效,并为我提供了 2 页的数据(100 个 unqiue 结果)

r1 = s.post(urls[0])
soup1 = bs(r1.content)
links1 = soup1.find_all('a', attrs={'data-link_text': "Profile Button"})
list1 = get_profile_link(links1)

r2 = s.post(urls[1])
soup2 = bs(r2.content)
links2 = soup2.find_all('a', attrs={'data-link_text': "Profile Button"})
list2 = get_profile_link(links2, list1)

方法 2:但是这不起作用,给我 100 个结果,只有 50 个唯一值

#A simplified version of loop to fetch results (I have a slightly complex one that generates url within the loop). 

for x in range(0, 2):
    r = s.post(urls[x])
    soup = bs(r.content)
    links = soup.find_all('a', attrs={'data-link_text': "Profile Button"})
    list = get_profile_link(links)

寻找有关我在Method 2中做错了什么的指导,因此我可以使用循环来提取链接。我认为它可以通过使用 cookie 来工作,我检查了一下print(r.cookies),似乎 cookie 没有生成/为空。我通读了文档,但无法清楚地弄清楚这一点。

如果需要更多详细信息,请告诉我。

标签: pythonweb-scrapingpython-requests

解决方案


最好不要在函数中使用列表默认参数(例如。profiles=[])。

此外,不要使用内置名称作为变量名称(例如。list)。

import requests
from bs4 import BeautifulSoup as bs

# Function to extract link href from each element in bs4 object
def get_profile_link(profile_links):
    rv = []
    for link in profile_links:
        rv.append(link["href"])
    return rv


all_data = []
base_url = "https://clutch.co/uk/app-developers?page="
with requests.session() as s:
    for page in range(0, 2):
        url = base_url + str(page)
        soup = bs(s.post(url).content, "html.parser")
        links = soup.find_all("a", attrs={"data-link_text": "Profile Button"})
        all_data.extend(get_profile_link(links))

print("Length of data:", len(all_data))
print("Unique elements:", len(set(all_data)))

印刷:

Length of data: 100
Unique elements: 100

推荐阅读