【问题标题】:How do you move to a new page when web scraping with BeautifulSoup?使用 BeautifulSoup 抓取网页时如何移动到新页面?
【发布时间】:2018-10-23 14:04:36
【问题描述】:

下面我有从 craigslist 中提取记录的代码。一切都很好,但我需要能够进入下一组记录并重复相同的过程,但对于编程来说,我被困住了。从查看页面代码看来,我应该单击此处跨度中包含的箭头按钮,直到它不包含 href:

<a href="/search/syp?s=120" class="button next" title="next page">next &gt; </a> 

我在想这可能是一个循环中的一个循环,但我想这也可能是一个尝试/例外情况。听起来对吗?你将如何实现它?

import requests
from urllib.request import urlopen
import pandas as pd

response = requests.get("https://nh.craigslist.org/d/computer-parts/search/syp")

soup = BeautifulSoup(response.text,"lxml")

listings = soup.find_all('li', class_= "result-row")

base_url = 'https://nh.craigslist.org/d/computer-parts/search/'

next_url = soup.find_all('a', class_= "button next")


dates = []
titles = []
prices = []
hoods = []

while base_url !=
    for listing in listings:
        datar = listing.find('time', {'class': ["result-date"]}).text
        dates.append(datar)

        title = listing.find('a', {'class': ["result-title"]}).text
        titles.append(title)

        try:
            price = listing.find('span', {'class': "result-price"}).text
            prices.append(price)
        except:
            prices.append('missing')

        try:
            hood = listing.find('span', {'class': "result-hood"}).text
            hoods.append(hood)
        except:
            hoods.append('missing')

#write the lists to a dataframe
listings_df = pd.DataFrame({'Date': dates, 'Titles' : titles, 'Price' : prices, 'Location' : hoods})

 #write to a file
listings_df.to_csv("craigslist_listings.csv")

【问题讨论】:

  • 每个页面的请求都应该在循环中进行。您需要确保 find_all 每次为下一页锚元素返回最多 1 个元素。然后循环的下一次迭代应该请求设置为该元素的href 属性的url。当无法再找到此元素或href 属性为空字符串时终止循环。

标签: python pandas beautifulsoup


【解决方案1】:

对于您抓取的每个页面,您都可以找到下一个要抓取的网址并将其添加到列表中。

这就是我会这样做的方式,而不会过多地更改您的代码。我添加了一些 cmets,以便您了解发生了什么,但如果您需要任何额外的解释,请给我留言:

import requests
from urllib.request import urlopen
import pandas as pd
from bs4 import BeautifulSoup


base_url = 'https://nh.craigslist.org/d/computer-parts/search/syp'
base_search_url = 'https://nh.craigslist.org'
urls = []
urls.append(base_url)
dates = []
titles = []
prices = []
hoods = []

while len(urls) > 0: # while we have urls to crawl
    print(urls)
    url = urls.pop(0) # removes the first element from the list of urls
    response = requests.get(url)
    soup = BeautifulSoup(response.text,"lxml")
    next_url = soup.find('a', class_= "button next") # finds the next urls to crawl
    if next_url: # if it's not an empty string
        urls.append(base_search_url + next_url['href']) # adds next url to crawl to the list of urls to crawl

    listings = soup.find_all('li', class_= "result-row") # get all current url listings
    # this is your code unchanged
    for listing in listings:
        datar = listing.find('time', {'class': ["result-date"]}).text
        dates.append(datar)

        title = listing.find('a', {'class': ["result-title"]}).text
        titles.append(title)

        try:
            price = listing.find('span', {'class': "result-price"}).text
            prices.append(price)
        except:
            prices.append('missing')

        try:
            hood = listing.find('span', {'class': "result-hood"}).text
            hoods.append(hood)
        except:
            hoods.append('missing')

#write the lists to a dataframe
listings_df = pd.DataFrame({'Date': dates, 'Titles' : titles, 'Price' : prices, 'Location' : hoods})

 #write to a file
listings_df.to_csv("craigslist_listings.csv")

编辑:您还忘记在您的代码中导入 BeautifulSoup,这是我在回复中添加的 Edit2:您只需要找到下一个按钮的第一个实例,因为页面可以(在这种情况下确实如此)有多个下一个按钮。
Edit3: 为了抓取计算机部件,base_url 应更改为此代码中存在的那个

【讨论】:

  • 太棒了!花了一些时间来浏览代码,但我很确定我理解发生的一切。非常感谢。
【解决方案2】:

这不是如何访问“下一步”按钮的直接答案,但这可能是您的问题的解决方案。当我过去进行网络抓取时,我使用每个页面的 URL 来循环搜索结果。 在 craiglist 上,当您单击“下一页”时,URL 会发生变化。通常,您可以利用这种更改的模式。我没有看很久,但看起来 craigslist 的第二页是:https://nh.craigslist.org/search/syp?s=120,第三页是https://nh.craigslist.org/search/syp?s=240。看起来 URL 的最后部分每次更改 120。 您可以创建一个 120 的倍数的列表,然后构建一个 for 循环以将此值添加到每个 URL 的末尾。 然后你将当前的 for 循环嵌套在这个 for 循环中。

【讨论】:

  • 这是我考虑过的一种方法,但我决定如果查询结束时有 100 页,例如,我可能不想列一个列表,但如果增量是一致的数量,那么我可以迭代 120 直到我没有返回结果.....我想。
猜你喜欢
  • 2018-01-18
  • 2020-09-17
  • 1970-01-01
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
  • 2020-03-27
  • 1970-01-01
相关资源
最近更新 更多