【问题标题】:Is there a way to remove excess spacing in Python code?有没有办法去除 Python 代码中多余的间距?
【发布时间】:2020-05-17 21:44:07
【问题描述】:

我下面的代码获取了每个健身房的街道地址,但是健身房开放时间的输出间隔有错误。关于我哪里出错的任何想法?

import urlparse

from bs4 import BeautifulSoup
from bs4 import Tag
import requests
import time
import csv

sitemap = 'https://www.planetfitness.com/sitemap'
sitemap_content = requests.get(sitemap).content
soup = BeautifulSoup(sitemap_content, 'html.parser')

atags = soup.select('td[class~=club-title] > a[href^="/gyms"]')
links = [atag.get('href') for atag in atags]

with open('gyms.csv', 'w') as gf:
    gymwriter = csv.writer(gf)
    for link in links:
        gymurl = urlparse.urljoin(sitemap, link)
        sitemap_content = requests.get(gymurl).content
        soup = BeautifulSoup(sitemap_content, 'html.parser')
        gymrow = [ gymurl ]

        address_line1 = soup.select('p[class~=address] > span[class~=address-line1]')
        gymrow.append(address_line1[0].text)
        locality = soup.select('p[class~=address] > span[class~=locality]')
        gymrow.append(locality[0].text)
        administrative_area = soup.select('p[class~=address] > span[class~=administrative-area]')
        gymrow.append(administrative_area[0].text)
        postal_code = soup.select('p[class~=address] > span[class~=postal-code]')
        gymrow.append(postal_code[0].text)
        country = soup.select('p[class~=address] > span[class~=country]')
        gymrow.append(country[0].text)

        strongs = soup.select('div > strong')
        for strong in strongs:
            if strong.text == 'Club Hours':
                for sibling in strong.next_siblings:
                    if isinstance(sibling, Tag):
                        hours = sibling.text
                        gymrow.append(hours)
                        break
        print(gymrow)
        gymwriter.writerow(gymrow)
        time.sleep(3)

感谢您的帮助!

【问题讨论】:

  • 您好,亲爱的回归 1234 - 非常感谢您提出问题。输出是什么 - 你没有输出吗?!?
  • 我在下面更新了我的答案以提取每个健身房的地址和时间。

标签: syntax-error spacing cellspacing line-spacing


【解决方案1】:

您要选择包含a 元素的td 元素(属于club-title 类),并提取href 属性。

from bs4 import BeautifulSoup
from bs4 import Tag
import requests
import urllib.parse
import time
import csv

sitemap = 'https://www.planetfitness.com/sitemap'
res = requests.get(sitemap).content
soup = BeautifulSoup(res, 'html.parser')

# The rows in the table of gyms are formatted like so:
# <tr>
# <td class="club-title"><a href="/gyms/albertville-al"><strong>Albertville, AL</strong> <p>5850 US Hwy 431</p></a></td>
# <td class="club-join"><div class="button"><a href="/gyms/albertville-al/offers" title="Join Albertville, AL">Join Now</a></div></td>
# </tr>

# This will find all the links to all the gyms.
atags = soup.select('td[class~=club-title] > a[href^="/gyms"]')
links = [atag.get('href') for atag in atags]

with open('gyms.csv', 'w') as gf:
    gymwriter = csv.writer(gf)
    for link in links:
        # Follow the link to this gym
        gymurl = urllib.parse.urljoin(sitemap, link)
        res = requests.get(gymurl).content
        soup = BeautifulSoup(res, 'html.parser')
        gymrow = [ gymurl ]

        # The address of this gym.
        address_line1 = soup.select('p[class~=address] > span[class~=address-line1]')
        gymrow.append(address_line1[0].text)
        locality = soup.select('p[class~=address] > span[class~=locality]')
        gymrow.append(locality[0].text)
        administrative_area = soup.select('p[class~=address] > span[class~=administrative-area]')
        gymrow.append(administrative_area[0].text)
        postal_code = soup.select('p[class~=address] > span[class~=postal-code]')
        gymrow.append(postal_code[0].text)
        country = soup.select('p[class~=address] > span[class~=country]')
        gymrow.append(country[0].text)

        # The hours of this gym.
        strongs = soup.select('div > strong')
        for strong in strongs:
            if strong.text == 'Club Hours':
                for sibling in strong.next_siblings:
                    if isinstance(sibling, Tag):
                        hours = sibling.text
                        gymrow.append(hours.replace('<br>', '').replace('\n', ', '))
                        break

        gymwriter.writerow(gymrow)
        time.sleep(3)

当我运行它时,我得到:

$ more gyms.csv

https://www.planetfitness.com/gyms/albertville-al,5850 US Hwy 431,Albertville,AL,35950,United States,"Monday-Friday 6am-9pm, Sat
urday-Sunday 7am-7pm"
https://www.planetfitness.com/gyms/alexander-city-al,987 Market Place,Alexander City,AL,35010,United States,Convenient hours whe
n we reopen
https://www.planetfitness.com/gyms/bessemer-al,528 W Town Plaza,Bessemer,AL,35020,United States,Convenient hours when we reopen
https://www.planetfitness.com/gyms/birmingham-crestline-al,4500 Montevallo Rd,Birmingham,AL,35210,United States,Convenient hours
 when we reopen
.
.
.

【讨论】:

  • 在回答您之前关于您收到的 AttributeError 的问题时,我将建议您 import urllib.parse 看看是否能解决问题。我继续并将其添加到我的答案中。
  • 更新了我的答案以包含 CSV 文件输出。
  • 试试this 看看是否有帮助。
  • 有问题字符的健身房的网址是什么?
  • 您应该在 writerow() 之前打印出 gymrow 并查看导致问题的原因。我有 BeautifulSoup 4.9.1 版,我没有你看到的问题。另外,请注意,并非所有健身房都有administrative-area,因此您必须添加一些保护代码来处理它。例如:planetfitness.do/gyms/santo-domingo-plaza-central-dr 我的总体建议是使用网络浏览器的“查看源代码”功能查看给您带来麻烦的网页内容,然后编写一些 Python 代码来处理特殊情况。
【解决方案2】:

要尝试调试它,您应该首先打印出 atags 的值。您正在搜索具有 clubs-list 类的所有 a 标记,其中不存在。 a 标签没有类,但其父标签td 具有类club-title

你可以试试这样的。

res = requests.get("https://www.planetfitness.com/sitemap").content
soup = BeautifulSoup(res, 'html.parser')

tds = soup.find_all('td', {'class': 'club-title'})
links = [td.find('a')['href'] for td in tds]
keywords = ['gyms']

for link in links:
    if any(keyword in link for keyword in keywords):
        print(link)

【讨论】:

  • 为此,您必须对每个单独的链接进行二次请求并从那里解析数据。
  • @Regression1234 暂时忘记要使用的工具/库。想想 Q。这里有一些提示。首先,您的 Q 由几个相互关联的组件组成。第一个组件是俱乐部地址,您会看到类似websitename/gyms/albertville-alwebsitename/gyms/alexander-city-al 的模式。考虑到这一点,您必须弄清楚如何构造 url。在urllib.parse 库中查找urljoin。因此,编写代码首先获取列表中的所有俱乐部地址 url,然后创建另一个包含完整 url 的列表,然后浏览到每个列表以获取数据。希望这是有道理的。
  • @Regression1234 使用requests.get(complete_url_address) 浏览页面。所以导入库请求。
  • @Regression1234 如果您可以使用迄今为止尝试过的内容更新您的 Q,那将是明智的。说明什么有效,什么无效。此后,只问 1 个您无法解决的特定问题。这样,你的 Q 就会表现出努力、研究和专注。希望这会有所帮助。
  • 问一个好的问题是一门艺术。而这个post 和这个minimal reprex 将帮助你掌握它。请参考它,理解然后修改你的Q。
【解决方案3】:

这将获取该页面上的每个链接和地址。看起来如果您想找到有关每个俱乐部的更多信息,您必须反复浏览并加载每个页面。

from bs4 import BeautifulSoup
import requests

res = requests.get("https://www.planetfitness.com/sitemap").content
soup = BeautifulSoup(res, 'html.parser')

atags = soup.find_all('td', {'class':'club-title'})

links = [(atag.find('a')['href'], atag.find('p').text) for atag in atags)]


[print(link) for link in links]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-23
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多