【问题标题】:Looping through pages but no results on pages after 1循环浏览页面但在 1 之后的页面上没有结果
【发布时间】:2021-11-26 19:49:23
【问题描述】:

我认为是缓存或 cookie 问题。当我在一个页面(任何页面)上运行我的代码时,它会给我该页面上的结果(大约 40 个列表)。例如,当我从范围 (1,4) 进行迭代以获取前 3 页时,第一页提供 40 个列表,但我得到第 2、3、4 页的 0 个结果。如果我只在第 2 页上运行我的代码,它会给我 40 个列表。我已经尝试实现重试方法并重试链接 10 次,但它没有工作。我还尝试在我的标题中旋转用户代理以在每个页面上使用不同的浏览器,但仍然无法正常工作。

我的代码如下,如果有任何见解,我将不胜感激。

import requests, pandas, random
from bs4 import BeautifulSoup
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

user_agent_list = [
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15',
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0',
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:77.0) Gecko/20100101 Firefox/77.0',
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
]

domain = "https://www.kijiji.ca"
base_url = ("https://www.kijiji.ca/b-cars-trucks/ontario/used/")
listCars = []  #empty list for final dictionaries

#100 pages constitutes ~17 hour cycles - to check once per 24h
for x in range(2,4):

    user_agent = random.choice(user_agent_list)
    getHeader = {'User-Agent': user_agent}
    new_url = base_url + f"page-{x}" + "/c174l9004a49"
    # r = session.get(new_url)
    try:
        r = requests.get(new_url, timeout=10, headers = getHeader)
        print("")
        print("Https Request Success: FULL PAGE {}:  {}".format(x, new_url))
        print("")
    except requests.exceptions.ConnectionError as e:
        print("")
        print("ERROR: Can't Get Page {}".format(x))
        print("")
        continue
    page = r.content 
    soup = BeautifulSoup(page, "html.parser")

    #list of every ad on page which should be looped through
    rows = soup.find_all("div", {"class": "regular-ad"})
    print("{} Results on Page {}.".format(len(rows), x))


    #looping through each single ad on index page
    for row in rows:
        carDictionary = {}
        ad_id = row.get("data-listing-id")
        ad_url = domain + row.get("data-vip-url")
        if "kijijiautos.ca" in ad_url:
            print("Skipped Invalid URL Ad")
            continue
        carDictionary["Ad ID"] = ad_id
        carDictionary["Ad URL"] = ad_url

        #getting price value
        carPriceRaw = row.find("div", {"class": "price"}).text.replace("\n", "").replace(" ","")
        try:
            if carPriceRaw == "Please Contact":
                carPrice = None
            elif carPriceRaw == "PleaseContact":
                carPrice = None
            else:
                carPrice = int(float(row.find("div", {"class": "price"}).text.replace("\n", "").replace(" ","").replace('$', '').replace(',', '')))
            carDictionary["Price"] = carPrice
        except (ValueError):
            continue

        #https request for individual ad to dissect specific information
        try:
            singlePgContent = requests.get(ad_url, timeout=5, headers = getHeader).content
            print("Https Request Success: SINGLE AD:  {}".format(ad_url))
        except requests.exceptions.ConnectionError as e:
            print("ERROR: LINK FAILED - SKIPPED: {}".format(ad_url))
            continue

        single_page = BeautifulSoup(singlePgContent, "html.parser")
        
        try:
            attributes = single_page.find("div", {"class": "attributeListWrapper-2108313769"}) #both columns of attributes - holds 5 children nodes, we just need the first 2 columns
            print("retrieved attributes")
            columns = attributes.find_all("ul", {"class": "itemAttributeList-1090551278"}) #each is a column
            
            first_col = columns[0]  #year, make, model, trim
            second_col = columns[1] #body type, drivetrain, transmission, kilometers
            first_col_attributes = first_col.find_all("li", {"class": "itemAttributeWrapper-37588635"})
            second_col_attributes = second_col.find_all("li", {"class": "itemAttributeWrapper-37588635"})
            
        except (AttributeError):
            print("Could not retrieve attributes")
            continue

        for attribute_li in first_col_attributes:
            try:  #to check and see if dt (attribute name) exists, otherwise skip iteration -eg. carfax report has no attribute name
                label = attribute_li.find("dl", {"class": "itemAttribute-3080139557"}).find("dt", {"class": "attributeLabel-240934283"}).text
            except:
                continue
            try:
                if label == "Year":
                    carYear = attribute_li.find("dl", {"class": "itemAttribute-3080139557"}).find("dd", {"class": "attributeValue-2574930263"}).text
                    carDictionary["Year"] = int(carYear)
            except (AttributeError, ValueError):
                continue
            try:
                if label == "Make":
                    carMake = attribute_li.find("dl", {"class": "itemAttribute-3080139557"}).find("dd", {"class": "attributeValue-2574930263"}).text
                    carDictionary["Make"] = carMake
            except (AttributeError, ValueError):
                continue
            try:
                if label == "Model":
                    carModel = attribute_li.find("dl", {"class": "itemAttribute-3080139557"}).find("dd", {"class": "attributeValue-2574930263"}).text
                    carDictionary["Model"] = carModel
            except (AttributeError, ValueError):
                continue
            try:
                if label == "Trim":
                    carTrim = attribute_li.find("dl", {"class": "itemAttribute-3080139557"}).find("dd", {"class": "attributeValue-2574930263"}).text
                    carDictionary["Trim"] = carTrim
            except (AttributeError):
                carDictionary["Trim"] = None

        for attribute_li in second_col_attributes:
            try:  #to check and see if dt (attribute name) exists, otherwise skip iteration -eg. carfax report has no attribute name
                label = attribute_li.find("dl", {"class": "itemAttribute-3080139557"}).find("dt", {"class": "attributeLabel-240934283"}).text
            except:
                continue
            try:
                if label == "Body Type":
                    carBody = attribute_li.find("dl", {"class": "itemAttribute-3080139557"}).find("dd", {"class": "attributeValue-2574930263"}).text
                    carDictionary["Body"] = carBody
            except (AttributeError):
                carDictionary["Body"] = None
            try:
                if label == "Transmission":
                    carTrans = attribute_li.find("dl", {"class": "itemAttribute-3080139557"}).find("dd", {"class": "attributeValue-2574930263"}).text
                    carDictionary["Transmission"] = carTrans
            except (AttributeError):
                carDictionary["Transmission"] = None
            try:
                if label == "Kilometers":
                    carKM = int(attribute_li.find("dl", {"class": "itemAttribute-3080139557"}).find("dd", {"class": "attributeValue-2574930263"}).text.replace(',', ''))
                    carDictionary["Kilometers"] = carKM
            except (AttributeError, ValueError):
                carDictionary["Kilometers"] = None
            try:
                if label == "Drivetrain":
                    carDrivetrain = attribute_li.find("dl", {"class": "itemAttribute-3080139557"}).find("dd", {"class": "attributeValue-2574930263"}).text
                    carDictionary["Drivetrain"] = carDrivetrain
            except (AttributeError):
                carDictionary["Drivetrain"] = None

        print(carDictionary)

        listCars.append(carDictionary)
        
df = pandas.DataFrame(listCars)
df.to_csv('cars.csv')
print(df)

输出给我:

第 2 页有 40 个结果。 第 3 页有 0 个结果。 然后打印包含汽车列表数据的字典列表的 pandas 数据框。

【问题讨论】:

    标签: python beautifulsoup python-requests


    【解决方案1】:

    您的代码在我的计算机上正常运行,例如:

    Https Request Success: FULL PAGE 2:  https://www.kijiji.ca/b-cars-trucks/ontario/used/page-2/c174l9004a49
    
    40 Results on Page 2.
    Https Request Success: SINGLE AD:  https://www.kijiji.ca/v-cars-trucks/chatham-kent/2009-bmw-328i-xdrive/1595980578
    retrieved attributes
    {'Ad ID': '1595980578', 'Ad URL': 'https://www.kijiji.ca/v-cars-trucks/chatham-kent/2009-bmw-328i-xdrive/1595980578', 'Price': 8000, 'Year': 2009, 'Make': 'BMW', 'Model': '3-Series', 'Trim': '328i xDrive', 'Body': 'Sedan', 'Drivetrain': 'All-wheel drive (AWD)', 'Transmission': 'Automatic', 'Kilometers': 191000}
    Https Request Success: SINGLE AD:  https://www.kijiji.ca/v-cars-trucks/markham-york-region/2020-kia-sorento-2-4l-lx-awd-owner-lowks/m2613367
    retrieved attributes
        Https Request Success: SINGLE AD:  https://www.kijiji.ca/v-cars-trucks/windsor-area-on/2018-hyundai-santa-fe-sport-luxury/m2567143
        retrieved attributes
        {'Ad ID': '2567143', 'Ad URL': 'https://www.kijiji.ca/v-cars-trucks/windsor-area-on/2018-hyundai-santa-fe-sport-luxury/m2567143', 'Price': 27225, 'Year': 2018, 'Make': 'Hyundai', 'Model': 'Santa Fe', 'Trim': 'Luxury', 'Drivetrain': 'All-wheel drive (AWD)', 'Transmission': 'Automatic', 'Kilometers': 57007}
       
    .....
     
    Https Request Success: FULL PAGE 3:  https://www.kijiji.ca/b-cars-trucks/ontario/used/page-3/c174l9004a49
    
    40 Results on Page 3.
    Https Request Success: SINGLE AD:  https://www.kijiji.ca/v-cars-trucks/windsor-area-on/2018-hyundai-santa-fe-sport-luxury/m2567143
    retrieved attributes
    {'Ad ID': '2567143', 'Ad URL': 'https://www.kijiji.ca/v-cars-trucks/windsor-area-on/2018-hyundai-santa-fe-sport-luxury/m2567143', 'Price': 27225, 'Year': 2018, 'Make': 'Hyundai', 'Model': 'Santa Fe', 'Trim': 'Luxury', 'Drivetrain': 'All-wheel drive (AWD)', 'Transmission': 'Automatic', 'Kilometers': 57007}
    Https Request Success: SINGLE AD:  https://www.kijiji.ca/v-cars-trucks/windsor-area-on/2019-hyundai-tucson-preferred/m2451609
    retrieved attributes
    

    所以我认为你的 ip 必须受到服务器的限制。因为你已经尝试了很多次请求让服务器在你的 ip 上做一些Rate Limit Strategies 的页面。也许changing your ip 会解决这个问题。

    【讨论】:

    • 我已经尝试更改我的 IP,但不幸的是我认为这并没有解决问题,我在后续页面上仍然得到 0 个结果。这很奇怪,因为 python 请求能够成功获取页面,但服务器没有加载任何结果。
    猜你喜欢
    • 1970-01-01
    • 2010-09-10
    • 2020-12-13
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多