为了账号安全,请及时绑定邮箱和手机立即绑定

我一点点查代码没问题,结果还是NameError: name 'new_urls' is not defined

class UrlManager(object):           ##url管理器,用于添加但不重复url,下面有四种

    def __init__(self):

        self.new_urls=set()

        self.old_urls=set()

    

    def add_new_url(self,url):           ##向管理器中添加一个新的URL,单个添加

        if url is None:

            return

        if url not in new_urls and url not in old_urls:  ##判断一个url既不在待爬去url群里也不在已经爬过的群 ,那么就把它加进待爬去

            self.new_urls.add(url)

        

    def add_new_urls(self,urls):              ##向管理器中添加一批的URL ,批量添加

        if urls is None or len(urls)==0:

            return

        for url in urls:

            self.add_new_url(url)

        

    def has_new_url(self):          ##判断是否有新的待爬取得url

        return len(self.new_urls)!=0         ##new_urls长度不为0,说明有待爬去的url

    

    def get_new_url(self):          ##从url管理器中获取一个url

        new_url=self.new_urls.pop()        ##pop获取一个的同时移除这个url,

        self.old_urls.add(new_url)

        return new_url

import urllib.request

class HtmlDownloader(object):

    def download(self,url):

        if url is None:

            return None

        response=urllib.request.urlopen(url)         ##这里使用了最简单的urllib下载方法,如果要用cookie则需要修改

        if response.getcode()!=200:

            return None

        return response.read()

from bs4 import BeautifulSoup

import re

##urllib.parse模块主要是把url拆分为6部分,并返回元组。并且可以把拆分后的部分再组成一个url。主要有函数有urljoin、urlsplit、urlunsplit、urlparse等。

import urllib.parse            

class HtmlParser(object):

    def _get_new_urls(self,page_url,soup):

        new_urls=set()                                                   ##结果存在urls列表里

        links=soup.find_all('a',href=re.compile(r"/doc/\d+\.html"))      ##"\d+\"用来指代数字串,re.compile实现正则模糊匹配

        for link in links:

            new_url=link['href']

            new_full_url=urllib.parse.urljoin(page_url,new_url)         ##new_url按照page_url的格式拼接成全新的url

            new_urls.add(new_full_url)

        return new_urls

    def _get_new_data(self,page_url,soup):

        res_data={}                                   ##存放数据

        res_data['url']=page_url                   ##url也放入最终数据中方便使用

        ##标题右键查看元素,然后右键edit as html得到<h1><span class="title">Python,这个用于确认find内的内容

        title_node=soup.find('span',class_="title").find("h1")

        res_data['title']=title_node.get_text()              ##获取标题数据

        ##获取方法同上得到<div class="card_content" id="js-card-content"><p>

        summary_node=soup.find('div',class_="card_content" )

        res_data['summary']=summary_node.get_text()            ##获取内容数据

        return res_data

        

    def parser(self,page_url,html_cont):

        if page_url is None or html_cont is None:

            return

        soup=BeautifulSoup(html_cont,'html.parser',from_encoding='utf-8')

        new_urls=self._get_new_urls(page_url,soup)

        new_data=self._get_new_data(page_url,soup)

        return new_urls,new_data

class HtmlOutputer(object):                     ##创建输出器的模块

    def __init__(self):

        self.datas=[]

    def collect_data(self,data):               ##收集数据

        if data is None:

            return

        self.datas.append(data)

    def output_html(self):                  ##输出数据写出到html文件中

        fout=open('output.html','w')        ##建立文件输出对象,output.html是输出文件的命名,w是模式

        

        fout.write("<html>")                 ##开始标签

        fout.write("<body>")

        fout.write("<table>")

        

        for data in self.datas:

            fout.write("<tr>")              ##写一个行的开始标签

            fout.write("<td>%s</td>"% data ['url'])             ##单元格的内容

            fout.write("<td>%s</td>"% data ['title'].encode('utf-8'))  ##python默认模式是ascii,如果输出utf-8,就末尾加上.encode('utf-8')

            fout.write("<td>%s</td>"% data ['summary'].encode('utf-8'))   ##如果没有.encode('utf-8'),有些中文可能识别成乱码

            fout.write("</tr>")

            

        fout.write("</table>")            ##跟上面相对应的闭合标签

        fout.write("</body>")

        fout.write("</html>")

        fout.close()

class SpiderMain(object):                              ##创建SpiderMain总调度程序和入口程序

    def __init__(self):                                      ##初始化UrlManager、HtmlDownloader等各个模块

        self.urls=UrlManager()                 ##url管理器   

        self.downloader=HtmlDownloader()    ##下载器     

        self.parser=HtmlParser()             ##解析器

        self.outpouter=HtmlOutputer()      ##输出器

        

    def craw(self,root_url):                                 ##爬虫调度程序

        count=1                                                    ##记录当前次数

        self.urls.add_new_url(root_url)                        ##入口url添加进url管理器

        while self.urls.has_new_url():                         ##有带爬取得url时,启动爬虫循环

            try:

                new_url=self.urls.get_new_url()                     ##获取一个url

                print('craw %d : %s' % (count,new_url))                     ##

                html_cont=self.downloader.download(new_url)                    ##启动下载器下载页面

                new_urls,new_data=self.parser.parse(new_url,html_cont)          ##解析页面数据,得到新的url列表和新的数据

                self.urls.add_new_urls(new_urls)                            ##url添加进url管理器,这里是urls添加了批量url,上面是单个url

                self.outputer.collect_data(new_data)               ## 收集数据

                if count==1000:             ##我们设置爬取1000个页面,达到1000个时就停止

                    break

                count+=1

            except:                                        ##有些url已经无法访问或无摘要数据,所以进行异常处理

                print("craw failed")

         

        self.outputer.output_html()                              ##输出收集好的数据


if __name__ =="__main__":     ##编写main函数,双下滑线

    root_url="https://baike.so.com/doc/1790119-1892991.html"     ##设置入口url,就是python360百科网站字符

    obj_spider=SpiderMain()             ##SpiderMain是总调度程序,前面创建了

    obj_spider.craw(root_url)            ##用spider启动爬虫


正在回答

1 回答

https://img1.sycdn.imooc.com//5d3bba0700018b9e09080848.jpg

把craw下面的代码对齐试试,其他该对齐的也对齐,我的就经常因为对不齐报错,个人建议,希望有用。

0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
Python开发简单爬虫
  • 参与学习       227670    人
  • 解答问题       1219    个

本教程带您解开python爬虫这门神奇技术的面纱

进入课程

我一点点查代码没问题,结果还是NameError: name 'new_urls' is not defined

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信