Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 无法使用set清除重复的结果_Python_Python 3.x_Web Scraping - Fatal编程技术网

Python 无法使用set清除重复的结果

Python 无法使用set清除重复的结果,python,python-3.x,web-scraping,Python,Python 3.x,Web Scraping,我已经用python编写了一个脚本,用于刮取位于标题为England的表下的所有链接,然后在脚本到达内部页面时使用这些链接,它将刮取下一个页面链接。我知道如果我修复脚本中使用的XPath,我可能会得到唯一的下一页URL 但是,这里的主要目标是确定为什么我的脚本即使在使用set()时也会产生重复的脚本 我的剧本: import requests from lxml.html import fromstring from urllib.parse import urljoin link = "ht

我已经用python编写了一个脚本,用于刮取位于标题为
England
的表下的所有链接,然后在脚本到达内部页面时使用这些链接,它将刮取下一个页面链接。我知道如果我修复脚本中使用的XPath,我可能会得到唯一的下一页URL

但是,这里的主要目标是确定为什么我的脚本即使在使用
set()
时也会产生重复的脚本

我的剧本:

import requests
from lxml.html import fromstring
from urllib.parse import urljoin

link = "http://tennishub.co.uk/"

processed_links = set()
processed_nextpage_links = set()

def get_links(url):
    response = requests.get(url)
    tree = fromstring(response.text)

    unprocessed_links = [urljoin(link,item.xpath('.//a/@href')[0]) for item in tree.xpath('//*[@class="countylist"]')]
    for nlink in unprocessed_links:
        if nlink not in processed_links:
            processed_links.add(nlink)
    get_nextpage_links(processed_links)

def get_nextpage_links(itemlinks):
    for ilink in itemlinks:
        response = requests.get(ilink)
        tree = fromstring(response.text)
        titles = [title.xpath('.//a/@href')[0] for title in tree.xpath('//div[@class="pagination"]') if title.xpath('.//a/@href')]
        for ititle in titles:
            if ititle not in processed_nextpage_links:
                processed_nextpage_links.add(ititle)

        for rlink in processed_nextpage_links:
            print(rlink)

if __name__ == '__main__':
    get_links(link)
结果我发现:

/tennis-clubs-by-county/Durham/2
/tennis-clubs-by-county/Durham/2
/tennis-clubs-by-county/Durham/2
/tennis-clubs-by-county/Cheshire/2
/tennis-clubs-by-county/Derbyshire/2
/tennis-clubs-by-county/Durham/2
/tennis-clubs-by-county/Cheshire/2
/tennis-clubs-by-county/Derbyshire/2
/tennis-clubs-by-county/Durham/2

每次调用
get\u nextpage\u links
时,您都在打印到目前为止收集的所有链接

我想您应该完全删除
打印
,完成后只打印列表,最好是在任何
定义
之外(使函数可重用,并将任何外部副作用推迟到调用代码)

没有全局变量的更好解决方案可能是让
get\u links
收集一个集合并返回它,在调用该集合时将对该集合的引用传递给
get\u nextpage\u links
,并且(显然)让该集合添加任何新链接


因为您使用的是集合,所以在添加链接之前,无需特别检查集合中是否已存在链接。无法将副本添加到此数据类型。

每次调用
get\u nextpage\u links
时,您都会打印到目前为止收集的所有链接

我想您应该完全删除
打印
,完成后只打印列表,最好是在任何
定义
之外(使函数可重用,并将任何外部副作用推迟到调用代码)

没有全局变量的更好解决方案可能是让
get\u links
收集一个集合并返回它,在调用该集合时将对该集合的引用传递给
get\u nextpage\u links
,并且(显然)让该集合添加任何新链接


因为您使用的是集合,所以在添加链接之前,无需特别检查集合中是否已存在链接。无法将副本添加到此数据类型。

每次呼叫时

        for rlink in processed_nextpage_links:
            print(rlink)

您之所以打印它,是因为您的for循环在for循环中,每次调用时都会在您的集合中添加链接

        for rlink in processed_nextpage_links:
            print(rlink)

打印它是因为for循环在for循环中,在集合中添加链接

请尝试以下脚本。事实证明,您的xapth有一些缺陷,这些缺陷是在解析多个块中的某个块,正如@tripleee在其评论中已经提到的(据推测)。我在脚本中使用了略微不同的
set()
。现在,它应该产生独特的链接

import requests
from lxml.html import fromstring
from urllib.parse import urljoin

link = "http://tennishub.co.uk/"

def get_links(url):
    response = requests.get(url)
    tree = fromstring(response.text)
    crude_links = set([urljoin(link,item) for item in tree.xpath('//*[@class="countylist"]//a/@href') if item])
    return crude_links

def get_nextpage(link):
    response = requests.get(link)
    tree = fromstring(response.text)
    titles = set([title for title in tree.xpath('//div[@class="pagination"]//a/@href') if title])
    return titles

if __name__ == '__main__':
    for next_page in get_links(link):
        for unique_link in get_nextpage(next_page):
            print(unique_link)

试试下面的脚本。事实证明,您的xapth有一些缺陷,这些缺陷是在解析多个块中的某个块,正如@tripleee在其评论中已经提到的(据推测)。我在脚本中使用了略微不同的
set()
。现在,它应该产生独特的链接

import requests
from lxml.html import fromstring
from urllib.parse import urljoin

link = "http://tennishub.co.uk/"

def get_links(url):
    response = requests.get(url)
    tree = fromstring(response.text)
    crude_links = set([urljoin(link,item) for item in tree.xpath('//*[@class="countylist"]//a/@href') if item])
    return crude_links

def get_nextpage(link):
    response = requests.get(link)
    tree = fromstring(response.text)
    titles = set([title for title in tree.xpath('//div[@class="pagination"]//a/@href') if title])
    return titles

if __name__ == '__main__':
    for next_page in get_links(link):
        for unique_link in get_nextpage(next_page):
            print(unique_link)

此外,您不必一直将记录保存在
set()
中,您可以使用
.append()
将它们附加到
列表中,然后在最后将它们转换为一个集合
unique\u records=set(所有记录的列表)
您也不必一直将记录保存在
set()
中,您可以使用
.append()
将它们附加到
列表
,然后在末尾将它们转换为一个集合
unique\u records=set(列出所有记录)
可能与此问题无关。我不打算访问一个不熟悉的网站,但通常情况下,您会发现XPath表达式只提取所需链接的子集,可能是因为它们的编码不一致,或者是因为XPath规范中存在错误。可能与此问题无关。我不打算访问一个不熟悉的网站,但通常,您会发现XPath表达式只提取您想要的链接的子集,可能是因为它们的编码不一致,或者是因为XPath规范中存在错误。