【问题标题】:Shaking off duplicates while parsing解析时去除重复项
【发布时间】:2017-08-31 00:14:08
【问题描述】:

我已经制作了一个用 python 编写的解析器,它完美地完成了它的工作,除了一些重复出现。此外,当我打开 csv 文件时,我可以看到每个结果都被方括号包围。是否有任何解决方法可以即时删除重复数据和方括号?这是我尝试过的:

import csv
import requests
from lxml import html
def parsingdata(mpg):
    data = set()
    outfile=open('RealYP.csv','w',newline='')
    writer=csv.writer(outfile)
    writer.writerow(["Name","Address","Phone"])
    pg=1
    while pg<=mpg:
        url="https://www.yellowpages.com/search?search_terms=Coffee%20Shops&geo_location_terms=Los%20Angeles%2C%20CA&page="+str(pg)
        page=requests.get(url)
        tree=html.fromstring(page.text)
        titles = tree.xpath('//div[@class="info"]')
        items = []
        for title in titles:
            comb = []
            Name = title.xpath('.//span[@itemprop="name"]/text()')
            Address = title.xpath('.//span[@itemprop="streetAddress" and @class="street-address"]/text()')
            Phone = title.xpath('.//div[@itemprop="telephone" and @class="phones phone primary"]/text()')
            try:
                comb.append(Name[0])
                comb.append(Address[0])
                comb.append(Phone[0])
            except:
                continue
            items.append(comb)

        pg+=1 
        for item in items:
            writer.writerow(item)
parsingdata(3)

现在它工作正常。 编辑:取自 bjpreisler 的更正部分

【问题讨论】:

  • 不阅读您的代码:丢弃重复项的规范解决方案是使用包含所有可见值的集合。在对你出现的下一个值进行任何操作之前,请检查它是否在集合中。
  • 感谢 timgeb 先生的回答。将尝试实施您刚才所说的内容,但我是新手,因此有时很难相应地维护指南。谢谢。
  • 尊敬的 timgeb 先生,我尝试按照您所说的进行操作,但这次它产生了 unhashable type: 'list' 错误。
  • 存储一个hashable类型,对应的元组或字符串。

标签: python csv web-scraping


【解决方案1】:

当我使用 .csv 文件时,此脚本会删除重复文件。检查这是否适合你:)

with open(file_out, 'w') as f_out, open(file_in, 'r') as f_in:
    # write rows from in-file to out-file until all the data is written
    checkDups = set() # set for removing duplicates
    for line in f_in:
        if line in checkDups: continue # skip duplicate
        checkDups.add(line)
        f_out.write(line)

【讨论】:

    【解决方案2】:

    您目前正在向 csv 写入一个列表(项目),这就是它在括号中的原因。为避免这种情况,请使用另一个可能如下所示的 for 循环:

     for title in titles:
            comb = []
            Name = title.xpath('.//span[@itemprop="name"]/text()')
            Address = title.xpath('.//span[@itemprop="streetAddress" and @class="street-address"]/text()')
            Phone = title.xpath('.//div[@itemprop="telephone" and @class="phones phone primary"]/text()')
            if Name:
                Name = Name[0]
            if Address:
                Address = Address[0]
            if Phone:
                Phone = Phone[0]
            comb.append(Name)
            comb.append(Address)
            comb.append(Phone)
            print comb
            items.append(comb)
    
    pg+=1 
    for item in items:
        writer.writerow(item)
    parsingdata(3)
    

    这应该将每个项目分别写入您的 csv。事实证明,您附加到 comb 的项目本身就是列表,所以这会提取它们。

    【讨论】:

    • 嗨,bjpreisler,感谢您的回答。我应用了你刚才的建议。它确实清除了方括号,但所有结果都进入一列而不是三列。
    • @SMth80,我编辑了上面的代码应该可以解决问题!
    • 感谢 bjpreisler,它完成了这项工作。顺便说一句,你能建议我在这种情况下如何正确使用 set() 来避免重复。
    • 您是希望消除名称重复(“星巴克”)还是仅在整个项目(名称、地址、电话)重复时才消除?
    • 不,不是这样。当我从 csv 文件中单击“删除重复项”选项时,刮掉了五页,它会删除一些重复项。但是通过数据我可以注意到它确实刮掉了一些具有相同值的项目。星巴克是一个不同的案例,因为您知道它虽然名称相同,但它包含的地址和电话号码彼此不同。谢谢。
    【解决方案3】:

    我最近发现的这个刮板的简洁版本是:

    import csv
    import requests
    from lxml import html
    
    url = "https://www.yellowpages.com/search?search_terms=Coffee%20Shops&geo_location_terms=Los%20Angeles%2C%20CA&page={0}"
    
    def parsingdata(link):
    
        outfile=open('YellowPage.csv','w',newline='')
        writer=csv.writer(outfile)
        writer.writerow(["Name","Address","Phone"])
    
        for page_link in [link.format(i) for i in range(1, 4)]:
            page = requests.get(page_link).text
            tree = html.fromstring(page)
    
            for title in tree.xpath('//div[@class="info"]'):
                Name = title.findtext('.//span[@itemprop="name"]')
                Address = title.findtext('.//span[@itemprop="streetAddress"]')
                Phone = title.findtext('.//div[@itemprop="telephone"]')
                print([Name, Address, Phone])
                writer.writerow([Name, Address, Phone])
    
    parsingdata(url)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 2016-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多