Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.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 无法推动为下一页生成的链接进行递归爬网_Python_Class_Web Scraping_Web Crawler - Fatal编程技术网

Python 无法推动为下一页生成的链接进行递归爬网

Python 无法推动为下一页生成的链接进行递归爬网,python,class,web-scraping,web-crawler,Python,Class,Web Scraping,Web Crawler,我创建的爬虫程序正在从网页获取名称和URL。现在,我无法让我的爬虫程序使用下一个页面生成的链接从下一个页面获取数据。我对使用类创建爬虫非常陌生,这是因为我无法进一步思考。我已经主动在我的代码中做了一些小改动,但它既不会带来任何结果,也不会抛出任何错误。希望有人能看看 import requests from lxml import html class wiseowl: def __init__(self,start_url): self.start_url=start

我创建的爬虫程序正在从网页获取名称和URL。现在,我无法让我的爬虫程序使用下一个页面生成的链接从下一个页面获取数据。我对使用类创建爬虫非常陌生,这是因为我无法进一步思考。我已经主动在我的代码中做了一些小改动,但它既不会带来任何结果,也不会抛出任何错误。希望有人能看看

import requests
from lxml import html

class wiseowl:
    def __init__(self,start_url):
        self.start_url=start_url
        self.storage=[]

    def crawl(self):
        self.get_link(self.start_url)

    def get_link(self,link):
        url="http://www.wiseowl.co.uk"
        response=requests.get(link)
        tree=html.fromstring(response.text)
        name=tree.xpath("//p[@class='woVideoListDefaultSeriesTitle']/a/text()")
        urls=tree.xpath("//p[@class='woVideoListDefaultSeriesTitle']/a/@href")
        docs=(name,urls)
        self.storage.append(docs)

        next_page=tree.xpath("//div[contains(concat(' ', @class, ' '), ' woPaging ')]//a[@class='woPagingItem']/@href")
        for npage in next_page:
            if npage is not None:
                self.get_link(url+npage)


    def __str__(self):
        return "{}".format(self.storage)


crawler=wiseowl("http://www.wiseowl.co.uk/videos/")
crawler.crawl()
for item in crawler.storage:
    print(item)

您应该考虑使用某种类型的数据结构来保存两个已访问的链接,以避免无限循环,并为尚未访问的链接创建一个容器。爬行本质上是互联网的广度优先搜索。因此,您应该使用谷歌广度优先搜索来更好地了解底层算法

为需要访问的链接实现一个队列。每次访问一个链接时,都要在页面上搜索所有链接并将每个链接排队。 在Python中实现一个集合或一个字典,以检查排队的每个链接是否已经被访问过,如果已经被访问过,则不要排队。 您的爬虫方法应该类似于:

def crawler(self):
while len(self.queue):
curr_link = self.queue.pop(0)
# process curr_link here -> scrape and add more links to queue
# mark curr_link  as visited

我修改了你们班的一些部分,试试看:

class wiseowl:
    def __init__(self,start_url):
        self.start_url=start_url
        self.links = [ self.start_url ]    #  a list of links to crawl # 
        self.storage=[]

    def crawl(self): 
        for link in self.links :    # call get_link for every link in self.links #
            self.get_link(link)

    def get_link(self,link):
        print('Crawling: ' + link)
        url="http://www.wiseowl.co.uk"
        response=requests.get(link)
        tree=html.fromstring(response.text)
        name=tree.xpath("//p[@class='woVideoListDefaultSeriesTitle']/a/text()")
        urls=tree.xpath("//p[@class='woVideoListDefaultSeriesTitle']/a/@href")
        docs=(name,urls)
        #docs=(name, [url+u for u in urls])    # use this line if you want to join the urls # 
        self.storage.append(docs)
        next_page=tree.xpath("//div[contains(concat(' ', @class, ' '), ' woPaging ')]//*[@class='woPagingItem' or @class='woPagingNext']/@href")    # get links form 'woPagingItem' or 'woPagingNext' # 
        for npage in next_page:
            if npage and url+npage not in self.links :    # don't get the same link twice # 
                self.links += [ url+npage ]

    def __str__(self):
        return "{}".format(self.storage)

crawler=wiseowl("http://www.wiseowl.co.uk/videos/")
crawler.crawl()
for item in crawler.storage:
    item = zip(item[0], item[1])
    for i in item : 
        print('{:60} {}'.format(i[0], i[1]))    # you can change 60 to the value you want # 

谢谢ryankdwyer的回答。事实上,我对循环比较熟悉。我不想在我的帖子中问我的循环的性质应该是什么,而是问我如何将我新创建的链接推进到该方法,以便它可以成为一个循环并获取我期望它做的事情。感谢t.m.adam爵士的回答。没有什么可以尝试的。每次你碰到我的乱七八糟的代码,它就像现在一样神奇。我还想从这里得到一件事:我怎样才能得到显示在两列中的结果,就像第一列中的视频标题和第二列中的链接一样。我的意思是结果代码被解析为列表。这都是我的错。再次感谢,先生。我更新了for循环,它打印了两列。如果您希望链接是完整的urlsOMG,您可以取消注释get_链接中的第8行!!!!!你在这里所做的完全出乎我的意料。它解决了所有问题。亚当先生万岁!!!!我很乐意帮忙: