我已经用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
答案 0 :(得分:2)
每次调用get_nextpage_links
时,您都将打印到目前为止收集的所有链接。
我想您会希望完全删除print
,并在完成后仅打印列表,最好在任何def
之外(使您的函数可重用,并将所有外部副作用推迟到调用代码)。
一个没有全局变量的更好的解决方案可能是让get_links
收集一个集合并返回它,并在每次调用它时将对该集合的引用传递给get_nextpage_links
,并且(显然)让它添加任何新链接。
由于使用的是集合,因此在添加链接之前不需要特别检查链接中是否已有链接。无法将重复项添加到此数据类型。
答案 1 :(得分:2)
尝试以下脚本。事实证明,您的xapth出现了一些缺陷,这些缺陷像@tripleee在其评论中已经提到的(可能是)从若干个特定块中进行了解析。我在follwong脚本中使用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)
答案 2 :(得分:1)
每次致电
for rlink in processed_nextpage_links:
print(rlink)
您正在打印它,因为您的for循环位于for循环内,从而在您的集合中添加了链接