【问题标题】:Python/BeautifulSoup Web-scraping Issue--Irregular ReturnsPython/BeautifulSoup 网页抓取问题--不规则返回
【发布时间】:2018-05-21 21:50:12
【问题描述】:

我已经搜索了问题/答案,并尝试对以下内容进行更改,但无济于事。

我正在尝试从 Coursera 的“数据分析”结果中抓取课程列表页面,https://www.coursera.org/browse/data-science/data-analysis?languages=en&page=1

共有 9 页,每页有 25 门课程,每门课程都有自己的 <h2> 标签。我发现以下代码取得了一些成功,但并不一致:

courses_data_sci = []
for i in range(10):
    page = "https://www.coursera.org/browse/data-science/data-analysis? languages=en&page=" + str(i)
    html = urlopen(page)
    soup = BeautifulSoup(html.read(), "html.parser")

for meta in soup.find_all('div', {'id' : 'rendered-content'}):
    for x in range(26):
        try:
            course = meta.find_all('h2')[x].text.strip()
            courses_data_sci.append(course)
        except IndexError:
            pass

这段代码似乎返回了前2-3页结果和最后一页结果;有时,如果我在清除courses_data_sci 后再次运行它,它会返回几次结果的第 4 页。 (我在 Jupyter 工作,我已经重新启动内核以解决那里的任何问题。)

我不确定为什么代码不能正常工作,更不用说为什么它返回不一致的结果了。

感谢任何帮助。谢谢你。

更新

感谢您的想法...我正在尝试利用两者来使代码正常工作。

出于好奇,我在考虑到两个 cmets 的情况下,缩减了代码以查看它得到了什么。

courses_data_sci = []
session = requests.Session()

for i in range(10):
    page = "https://www.coursera.org/browse/data-science/data-analysis? languages=en&page=" + str(i)
    html = urlopen(page)
    soup = BeautifulSoup(html.read(), "html.parser")

    for meta in soup.find_all('div', {'id' : 'rendered-content'}):
        course = meta.find_all('h2')
        courses_data_sci.append(course)


    # This is to check length of courses_data_sci across pages
    print('Page: %s  -- total length %s' % (i, len(courses_data_sci)))

这实际上会产生一个列表列表,确实包含整个 9 页的所有课程(当然还有 href 信息,因为它还没有被剥离)。每个循环每页创建一个列表:相应页面上所有课程的列表。所以看起来我应该能够在列表被推送到列表courses_data_sci 时剥离href

每个课程有 2 个<h2> 标签,所以我还认为第二个range() 调用可能存在问题:for x in range(26)。我尝试了多个不同的范围,但都没有工作或返回错误,“索引超出范围”。

【问题讨论】:

  • 保存每个页面的 HTML 并查看它。您可能没有得到您认为的页面和/或页面可能有不同的标记。

标签: python html web-scraping beautifulsoup


【解决方案1】:

我使用你的代码得到了同样的行为。

为了使用请求,我改变了它:

from bs4 import BeautifulSoup
import requests

courses_data_sci = []
session = requests.Session()

for i in range(10):
    page = "https://www.coursera.org/browse/data-science/data-analysis?languages=en&page=" + str(i)
    html = session.get(page)
    soup = BeautifulSoup(html.text, "html.parser")

    for meta in soup.find_all('div', {'id' : 'rendered-content'}):
        for x in range(26):
            try:
                course = meta.find_all('h2')[x].text.strip()
                courses_data_sci.append(course)
            except IndexError:
                pass

    # This is to check length of courses_data_sci across pages
    print('Page: %s  -- total length %s' % (i, len(courses_data_sci)))

【讨论】:

  • 感谢您的代码。不幸的是,.Session 没用。如果你有兴趣进一步研究它,我已经改变了我原来的帖子。我只是想看看如果我削减try / except 会发生什么,折叠来自@antfuentes87 的想法
  • 这段代码对我有用,我可以得到完整的列表。 Bur您必须使用我编写的代码;即不仅添加 Session 行,还使用 ​​session 获取页面: html = session.get(page) 然后使用 html.text 获取内容,如 soup = BeautifulSoup(html.text....)
  • 是的,你是对的,@GDN。当我尝试它时,我正在双重导入库,这似乎阻止了代码工作。我真的很感谢你的后续评论,这样我就没有继续旋转我的轮子了!非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-25
  • 2014-06-20
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
  • 1970-01-01
相关资源
最近更新 更多