【问题标题】:Issue with designing function for data scraping using BS4使用 BS4 设计数据抓取功能的问题
【发布时间】:2013-02-11 10:20:53
【问题描述】:

我需要的数据存在于tag + class 的两种不同组合中。我希望我的函数在这两种组合下进行搜索并同时呈现这两种组合下的数据。这两种组合是互斥的。如果存在 1 个组合,则不存在其他组合。

我使用的代码是:

# -*- coding: cp1252 -*-
import csv
import urllib2
import sys
import urllib
import time
from bs4 import BeautifulSoup
from itertools import islice

def match_both2(arg1,arg2):
    if arg1 == 'div' and arg2 == 'DetailInternetFirstContent empty openPostIt':
        return True
    if arg1 == 'p' and arg2 == 'connection':
        return True
    return False


page = urllib2.urlopen('http://www.sfr.fr/mobile/offres/toutes-les-offres-sfr?vue=000029#sfrintid=V_nav_mob_offre-abo&sfrclicid=V_nav_mob_offre-abo').read()
soup = BeautifulSoup(page)

datas = soup.findAll(match_both2(0),{'class':match_both2(1)})
print datas

现在,我正在尝试使用 match_both2 函数来完成此操作,但它给了我 TypeError 因为我只向它传递了 1 个参数并且它需要 2 个。我不知道在这种情况下如何将 2 个参数传递给它,通常我会调用类似 match_both2(example1,example2) 的函数。但是在这里,我想不出一种可以解决我的问题的方法。

请帮我解决这个问题。

【问题讨论】:

    标签: python python-2.7 beautifulsoup


    【解决方案1】:

    当您使用函数来过滤匹配元素时,您传递的只是对函数的引用,而不是结果。换句话说,您应该在将它传递给.findAll()之前调用它。

    该函数仅使用 一个 参数调用,即元素本身。此外,class 属性已被拆分为一个列表。因此,要匹配您的特定元素,您需要将匹配功能区分为:

    def match_either(tag):
        if tag.name == 'div':
            # at *least* these three classes must be present
            return {'DetailInternetFirstContent', 'empty', 'openPostIt'}.issubset(tag.get('class', []))
        if tag.name == 'p':
            # at *least* this one class must be present
            return 'connection' in tag.get('class', [])
    

    此函数返回True 用于带有connection 类的p 标记,或带有所有三个类的div 标记。

    将此传递给findAll() 不要调用它

    datas = soup.findAll(match_either)
    

    【讨论】:

    • 非常感谢!对于像我这样的初学者来说,你是一个很大的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 2020-10-10
    • 2019-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多