BeautifulSoup 不会使用 .find_all('a') 抓取页面中的所有锚标记。我忽略了啥吗?

Posted

技术标签:

【中文标题】BeautifulSoup 不会使用 .find_all(\'a\') 抓取页面中的所有锚标记。我忽略了啥吗?【英文标题】:BeautifulSoup is not scraping ALL anchor tags in a page with .find_all('a'). Am I overlooking something?BeautifulSoup 不会使用 .find_all('a') 抓取页面中的所有锚标记。我忽略了什么吗? 【发布时间】:2014-02-06 09:13:42 【问题描述】:

好的,所以在终端中,在导入和制作必要的对象之后——我输入:

for links in soup.find_all('a'):
     print(links.get('href'))

它给了我***页面上的所有链接(大约 250 个)。没问题。

但是,在我正在编写的程序中,我只收到大约 60 个链接(这是在抓取同一个***页面),而我得到的那些链接大多一文不值。我仔细检查了我的初始化是否完全相同——唯一的区别是变量的名称。作为参考,这是我设置 BS4 对象并获取所需页面的函数:

def get_site(hyperLink):
    userSite = urllib3.PoolManager()
    siteData = userSite.request("GET", hyperLink)
    bsd = BeautifulSoup(siteData.data)
    return bsd

稍后,我抓取这些元素并将它们附加到一个列表中,然后我将对其进行操作:

def find_urls(bsd, urls, currentNetloc):
    for links in bsd.find_all('a'):
        urls.append(links.get('href'))
    return urls

其他相关信息:

我使用的是 Python 3.3 我正在使用 urllib3、BeautifulSoup 4 和 urlparse(来自 urllib) 我在 PyCharm 工作(用于实际程序) 如果重要,请使用 Lubuntu。

在运行 python3 的命令行实例并导入“sys”后,我输入并收到:

$ sys.executable
'/usr/bin/python3'
$ sys.path
['', '/usr/local/lib/python3.3/dist-packages/setuptools-1.1.5-py3.3.egg', '/usr/local/lib/python3.3/dist-packages/pip-1.4.1-py3.3.egg', '/usr/local/lib/python3.3/dist-packages/beautifulsoup4-4.3.2-py3.3.egg', '/usr/lib/python3.3', '/usr/lib/python3.3/plat-i386-linux-gnu', '/usr/lib/python3.3/lib-dynload', '/usr/local/lib/python3.3/dist-packages', '/usr/lib/python3/dist-packages']

在 Pycharm 项目中运行这些命令后,我收到了完全相同的结果,除了包含我的 pycharm 项目的目录包含在列表中。

【问题讨论】:

你能举一个你遇到这些问题的***页面的例子吗? 是的。例如,我用en.m.wikipedia.org/wiki/Lyceum_(Classical) 做了很多测试。我注意到在终端中我得到了一个链接,比如“古希腊”,但是在我的编码项目中,它几乎跳过了该页面内容中的所有链接,并且大部分都是通用链接。 再次检查:您在终端中使用的解释器和 PyCharm 使用的解释器是否相同? 当我通过 py charm 运行程序时,缺少抓取的 url。当我说通过终端正常运行它时,我的意思是一个实际的 Linux 终端。如果你的问题是关于哪个版本的 python,那么是的,我在命令行和 pycharm 中都使用了 python 3 对于简短和任何语法错误,我也很抱歉,我现在正在打电话。 【参考方案1】:

我在网页抓取项目中遇到了很多问题;然而,BeautifulSoup 从来都不是罪魁祸首。

我高度怀疑你遇到了我在抓取***时遇到的同样问题。 Wikipedia 不喜欢我的用户代理,并且返回的页面与我请求的页面不同。尝试在您的代码中添加用户代理,例如 Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/33.0.1750.146 Safari/537.36

您提到您使用的是 urllib3,因此您可以在 here 阅读有关如何使用自定义用户代理的信息。

此外,如果您想诊断您的问题,请尝试以下操作:在您说一切正常的终端中,添加一个额外的行 print len(html) 然后在您的程序中执行相同操作,看看您是否真的从同一页。

【讨论】:

【参考方案2】:

这不是我的答案。我是从here 那里得到的,它以前对我有帮助。

    from bs4 import BeautifulSoup
    import csv

    # Create .csv file with headers
    f=csv.writer(open("nyccMeetings.csv","w"))
    f.writerow(["Name", "Date", "Time", "Location", "Topic"])

    # Use python html parser to avoid truncation
    htmlContent = open("nyccMeetings.html")
    soup = BeautifulSoup(htmlContent,"html.parser")

    # Find each row
    rows = soup.find_all('tr')
    for tr in rows:
        cols = tr.find_all('td') # Find each column
        try:
            names = cols[0].get_text().encode('utf-8')
            date = cols[1].get_text().encode('utf-8')
            time = cols[2].get_text().encode('utf-8')
            location = cols[3].get_text().encode('utf-8')
            topic = cols[4].get_text().encode('utf-8')
       except:
            continue
       # Write to .csv file
       f.writerow([names, date, time, location, topic])

我认为记录下我在编写此脚本时遇到的一些麻烦会很有用:

指定您的解析器。指定 BeautifulSoup 将用来解析 html 树形的 html 解析器的类型非常重要。我读入 Python 的 html 文件格式不正确,因此 BeautifulSoup 截断了 html,我只能访问大约四分之一的记录。通过告诉 BeautifulSoup 显式使用内置的 Python html 解析器,我能够避免这个问题并检索所有记录。

编码为 UTF-8。 get_text() 在对 html 标签内的文本进行编码时遇到了一些问题。因此,我无法将数据写入逗号分隔的文件。通过明确告诉程序编码为 UTF-8,我们完全避免了这个问题。

【讨论】:

请在这里回答问题。链接可能会失效。

以上是关于BeautifulSoup 不会使用 .find_all('a') 抓取页面中的所有锚标记。我忽略了啥吗?的主要内容,如果未能解决你的问题,请参考以下文章

Python笔记-BeautifulSoup中find_all的使用及str中trim()

Web爬虫递归BeautifulSoup

beautifulsoup:在 bs4.element.ResultSet 对象或列表上找到_all?

使用beautifulsoup在html中查找文本

BeautifulSoup抓取列表页锚文本

BeautifulSoup解析网页