【问题标题】:Urllib and BeautifulSoup flexible urlopen() optionsUrllib 和 BeautifulSoup 灵活的 urlopen() 选项
【发布时间】:2016-05-07 20:26:37
【问题描述】:

你们对我的最后一个问题非常有帮助,所以我想就我一直面临的问题提出一个新问题。我导入了 BeautifulSoup,并试图从该站点上的医学院数据库中导出数据:https://services.aamc.org/msar/home。我创建了一个“for”循环来打开和解析网站,然后从包含学校所在城市和州的特定跨度打印数据。执行代码后,我很兴奋地发现我的代码正在运行!!..并且很沮丧地看到它在第三次学习后返回错误。在窥探一个可能的问题时,我看到我从中提取数据的一些学校使用了 URL“https://services.aamc.org/msar/programDetails/(code)/about”,而不是 https://services.aamc.org/msar/schoolDetails/(code)/about(我已在代码中设置为我的 url),因此我的程序试图从不存在的网页中提取跨度数据!

有没有人知道在我的“url =”中定义一个 url 的方法,上面写着“识别这个 url 或那个 url”,或者可以选择跳过该部分 url 并简单地匹配代码和 /about网址的一部分?最重要的是代码以与数据库中出现的相同顺序返回城市信息,因为我会将所有这些数据导入 CSV 格式的列中并排列它们。所以不能乱序。

谢谢,非常感谢您的帮助。

Matt(抱歉下面的部分代码没有出现在代码窗口中!)


import requests
from urllib2 import urlopen
from bs4 import BeautifulSoup

url = "https://services.aamc.org/msar/home#null"
search_url = "https://services.aamc.org/msar/search/resultData"

with requests.Session() as session:
    session.get(url)  # visit main page

    # search
    data = {
        "start": "0",
        "limit": "500",
        "sort": "",
        "dir": "",
        "newSearch": "true",
        "msarYear": ""
    }
    response = session.post(search_url, data=data)
    import csv
    # extract search results
    results = response.json()["searchResults"]["rows"]

    codes = []

    for result in results:
        codes.append(int(result["key"]))


for code in codes:
    url = "https://services.aamc.org/msar/schoolDetails/%d/about" % code
    soup = BeautifulSoup(urlopen(url))

    city = soup.find("span", {"style": "font-size: 16px; font-weight: bold;"})

    for span in city:
        print(span)

【问题讨论】:

  • ["searchResults"]["rows"] 是否包含有关正确 URL 的信息?
  • 是的,所以如果您查看“search_url”,您将在主页“services.aamc.org/msar/home”上看到所有信息的代码。我正在尝试进入每所学校的页面(services.aamc.org/msar/schoolDetails/%d/about"% 代码)并抓取城市。问题是,有时个别学校的网站是"services.aamc.org/msar/schoolDetails/%d/about"% 代码",有时是"@ 987654327@" % code"。我不知道 BeautifulSoup 中的命令允许 url 中的字符串为 *“schoolDetails”或“programDetails”
  • 我在想“if/else 语句可能有效”,但我不确定。
  • 我在“search_url”页面上看不到有关每所学校正确 URL 的任何信息,是正确的还是我遗漏了什么?
  • 所以你是对的。我告诉它要做的是导航到主页services.aamc.org/msar/home 列表中每所学校的站点。如果您单击一个(例如奥尔巴尼医学院),然后单击下一个(阿尔伯特爱因斯坦),您会看到除了代码“https:...Details/[code]/about”之外的 URL 是相同的。我从 search_url 获得了这些代码,并尝试制作一个 for 循环以将此代码插入基本的 https 模板“services.aamc.org/msar/schoolDetails/[code]/about”。问题是,有些学校代码前没有“schoolDetails”,而是“programDetails”。

标签: python beautifulsoup urlopen


【解决方案1】:

假设事先没有关于每所学校正确 URL 的信息,您可以使用 try ... except... 构造尝试第一种 URL 格式,然后仅在第一个返回的“找不到页面”时尝试第二种 URL 格式(将不太可能的 URL(如果有)放在 url2 中,以尽量减少未命中情况):

from urllib2 import urlopen, HTTPError
.....

url1 = "https://services.aamc.org/msar/schoolDetails/%d/about"
url2 = "https://services.aamc.org/msar/programDetails/%d/about"
for code in codes:
    soup = None

    try:
        soup = BeautifulSoup(urlopen(url1 % code))
    except HTTPError as e:
        if e.getcode() == 404: # page not found
            print("first URL not found, trying the second URL...")
            soup = BeautifulSoup(urlopen(url2 % code))

    city = soup.find("span", {"style": "font-size: 16px; font-weight: bold;"})

【讨论】:

  • 这可行,但无法从链接中包含“programDetails”的所有站点中提取数据。我认为这是因为这些网站弹出的错误是。这似乎是因为它仍然无法执行 try/except 函数,因此该站点不可读。错误代码是“TypeError: 'NoneType' object is not iterable”。它将这些值保留为无。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-09
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
  • 2018-09-29
  • 1970-01-01
相关资源
最近更新 更多