百度360必应搜狗淘宝本站头条
当前位置:网站首页 > SEO教程 > 正文

【20201013】做个搜索引擎(7)网页蜘蛛代码编写(三)

gaoyangw 2024-11-05 10:30 24 浏览 0 评论

介绍

介绍

福哥更新了Spider对象,实现了爬取网页内容,分析网页数据,写入数据库这些功能。实现了这些功能之后网页蜘蛛的基本功能也就差不多完成了!后面就可以开始编写搜索引擎的前端UI功能了,相对网页蜘蛛来说,搜索引擎前端UI就比较简单了!

但是,网页蜘蛛是搜索引擎的基础,只有采集到足够多的数据,搜索引擎才可以在也会查询的时候返回用户想看到的结果内容。所以,今天这一课童鞋们一定要好好学习了!

增加字段

在前面设计数据表的时候出了一个纰漏,福哥没有在webpages数据表里建立与websites数据表的关联键,这样就无法在webpages里提取一个域名下的所有网页信息了。

新增字段

我们需要在webpages数据表里增加关联键字段websiteId用来关联websites数据表的主键字段。

SQL

SQL语句如下

mysql> alter table webpages add column websiteId int not null after webpageId, add key websiteId (websiteId);
Query OK, 0 rows affected (0.18 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql>

Spider对象

方法

getPendingPages

    def getPendingPages(self, domainName, nums):
        try:
            self.mysqlCS.execute("SELECT * FROM websites WHERE domainName = %s", [domainName])
            row = self.mysqlCS.fetchone()
            if row is not None:
                websiteId = row[0]
                self.mysqlCS.execute("SELECT * FROM webpages WHERE websiteId = %s ORDER BY lastFetchDT DESC LIMIT %s", [websiteId, nums])
                rows = self.mysqlCS.fetchall()

                return rows
        except Exception as e:
            print ("Fail to getPendingPages")
            print e
            self.mysqlCN.rollback()

        return None

analyzePage

    def analyzePage(self, url):
        title = self.chrome.title
        keywords = ""
        description = ""
        charset = ""
        pageSource = self.chrome.page_source
        stRE = re.compile("<\/?[a-z0-9]+[^\>]*>", re.M | re.I)
        scriptRE = re.compile("<(script).*?>[\s\S]*?<\/\1>", re.M | re.I)
        bcRE = re.compile("[\s\t\r\n]+", re.M | re.I)
        pageText = self.chrome.page_source.encode("gbk", "ignore")
        pageText = re.sub(stRE, " ", pageText)
        pageText = re.sub(scriptRE, " ", pageText)
        pageText = re.sub(bcRE, " ", pageText)
        pageText = pageText.decode("gbk")
        metas = self.chrome.find_elements_by_tag_name("meta")
        for meta in metas:
            myName = meta.get_attribute("name")
            myContent = meta.get_attribute("content")
            myHttpEquiv = meta.get_attribute("http-equiv")
            if myName == "keywords":
                keywords = myContent
            elif myName == "description":
                description = myContent
            elif myHttpEquiv is not None and myHttpEquiv.lower() == "content-type":
                myCharset = myContent
                csRE = re.compile("charset\=([^\;]+)", re.M | re.I)
                mats = csRE.search(myCharset)
                if mats:
                    charset=mats.group(1).lower()

        return {"url": url, "title": title, "keywords": keywords, "description": description, "charset": charset, "pageText":pageText}

findAllATags

    def findAllATags(self, websiteId, domainName):
        links = self.chrome.find_elements_by_tag_name("a")
        for link in links:
            try:
                myHref = link.get_attribute("href").encode("gbk")
                myWebPageType = self.isWebPage(myHref, domainName)
                if myWebPageType == 1:
                    ret = self.saveWebPage(websiteId, myHref)
                elif myWebPageType == 2:
                    lnkRE = re.compile("^(http|https)\:\/\/([^\/]+)", re.M | re.I)
                    mats = lnkRE.search(myHref)
                    if mats:
                        ret = self.saveDomainPage(mats.group(2).lower())
            except Exception as e:
                doNothing = e

fetchDomainURL

    def fetchDomainURL(self, websiteId, domainName):
        # open page of domain
        url = "http://" + domainName
        print ("打开网址:" + url)
        self.chrome.get(url)
        
        # find all A tags
        self.findAllATags(websiteId, domainName)

fetchWebURL

    def fetchWebURL(self, websiteId, domainName, url):
        # open page of url
        print ("打开网址:" + url)
        self.chrome.get(url)
        
        # find all A tags
        self.findAllATags(websiteId, domainName)

fetchDomainPageURL

    def fetchDomainPageURL(self, websiteId, domainName, webpageId, url):
        # open page of url
        print ("打开网页: " + url)
        self.chrome.get(url)

        # analyze page
        print ("分析网页: " + url)
        args = self.analyzePage(url)

        # save web page full data
        self.updateWebPage(webpageId, args)

        # find all A tags
        self.findAllATags(websiteId, domainName)

saveWebPage

    def saveWebPage(self, websiteId, url):
        # try to insert url into webpages
        try:
            self.mysqlCS.execute("SELECT * FROM webpages WHERE url = %s", [url])
            row = self.mysqlCS.fetchone()
            if row is None:
                self.mysqlCS.execute("INSERT INTO webpages (websiteId, url, statusCode, charset, createDT) VALUES (%s, %s, %s, %s, now())", [websiteId, url, 200, 1])
                self.mysqlCN.commit()
                print ("保存网页: " + url)

                return self.mysqlCS.lastrowid
            else:

                return row[0]
        except Exception as e:
            print ("Fail to saveWebPage")
            print e

        return None

updateWebPage

    def updateWebPage(self, webpageId, args):
        try:
            self.mysqlCS.execute("UPDATE webpages SET title = %s, keywords = %s, description = %s, lastFetchDT = now() WHERE webpageId = %s",
                [args["title"], args["keywords"].encode("utf-8"), args["description"].encode("utf-8"), webpageId])
            self.mysqlCN.commit()
            print ("更新网页: " + args["url"])

            return webpageId
        except Exception as e:
            print ("Failed to updateWebPage")
            print e

        return None

主程序

主程序代码也有所更新,除了之前进行的域名爬取处理之外,还增加了对域名下面的网页的爬取处理。

from lib.Spider import *

mySpider = Spider()

mySpider.open()
domains = mySpider.getPendingDomains(10)
if domains is not None:
    for domain in domains:
        mySpider.fetchDomainURL(domain[0], domain[1])
        pages = mySpider.getPendingPages(domain[1], 100)
        if pages is not None:
            for page in pages:
                mySpider.fetchDomainPageURL(domain[0], domain[1], page[0], page[2])
mySpider.close()

讲解

getPendingPages

通过域名获取到websites数据表的相关记录

通过websites.websiteId字段的值在webpages表里查询出指定数量的该域名所属的网页信息

analyzePage

使用正则表达式将meta信息里面的charset信息提取出来了

findAllATags

增加了websiteId参数,传递给saveWebPage方法

fetchDomainURL

增加了websiteId参数,传递给findAllATags方法

fetchWebURL

增加了websiteId参数,传递给findAllATags方法

fetchDomainPageURL

打开指定的url的网页

分析网页的信息,包括标题、关键字、描述等等信息

将网页的信息更新到webpages数据表里面

扫描网页的超链接,提取子级页面网址

saveWebPage

增加了websiteId参数,在写入webpages数据表的时候传递websiteId参数

updateWebPage

根据webpageId更新webpages数据表的相关字段的值

总结

我们的网页蜘蛛已经完成80%以上了,剩下的就是把网页的文字数据提取出来写入到数据库当中,同时将数据库当中的网页数据同步到ElasticSearch搜索引擎里面,采集的工作就算基本完成了!

下一节课,福哥将带着大家完成网页蜘蛛的最后一部分代码的编写,大家要好好学习哦~~


P.S.

微信公众号的文章发出去之后是不能编辑的,但是福哥偶尔会修复一些描述不到位、示例不正确、结构不清晰等等的文章错误,这些只能在网站上才能看到最新版本内容,望大家知晓~~


https://m.tongfu.net/home/35/blog/512811.html

相关推荐

「柒哥说」SEO推广的出路在哪里?(seo的推广技巧)

事情的成败以结果为断,中间的波折不足为论。——佚名随着近年来百度对黑帽优化的持续打击,这几年做优化的公司倒闭了很多,也让很多公司走向了两个极端面,要么放弃做白帽优化,只做付费推广,要么一门心思做白...

使用ESP32-CAM开发板链接OV2640摄像头网页显示

ESP32-CAMOV2640摄像头模块简介下载接线及配置例程说明输出图像总结模块简介本次实验使用的是ESP32-CAM模块,是全新的WIFI+蓝牙双模开发板,内核采用的双核的32位CPU,是基于E...

用golang抓取网页有多简单?(golang做网站)

之前有一个需求需要抓取网络上公开的网页数据,网页的代码大致如下:需要抓取的数据一共4处,结构并没有什么规律,而且分散。但是使用golang却可以很轻松地获取到所需要的数据,而且代码量很少。doc,_...

日本金泽工业大学开发出“追踪用户眼球运动,自动放大网页内容”的技术

据impress网站2月10日报道,日本金泽工业大学于2月宣布,它已经使用AI开发了一个“视线追踪演示系统”。研究人员表示:当视力低下的人或老年人在智能手机或PC上浏览网站时,他们通常会发现遇到难以阅...

前端开发基础课分享1--教你写第一个网页,开启前端大神之路

HTML编辑器推荐可以使用专业的HTML编辑器来编辑HTML,菜鸟教程为大家推荐几款常用的编辑器:VSCode:https://code.visualstudio.com/SublimeT...

2025最新!网页设计行业前沿理念与趋势白皮书

视频直播app和网页版怎么开发?(视频直播app和网页版怎么开发软件)

视频直播APP和网页开发定制的几个功能点:1、直播类软件最主要的功能是支持手机APP端和电脑端视频直播推流,稳定低延迟,保障画面传输流畅、清晰。2、主播直接连麦PK、和用户互动聊天,包括文字和表情等3...

国外网页/移动端手机开发组件ui工具包欣赏

网上有很多可用的webui工具包,让你可以简单的创建一个易于使用的和有吸引力的界面。然而,许多网页设计师都会同意,找到一个好的网页设计工具可以轻松的克服网页设计项目中的挑战。有一件好事是,我们准备了...

你要做的是网页设计,还是前端开发?

很多同学自己的专业,不是网页相关的专业。如不是计算机专业还是设计专业。初学者,傻傻分不清web设计和web开发,就以为"做"几个简单网页就是设计,用ps做几个网页设计稿,就是做网页。这样导致:你不知道...

前端如何开发3D网页?(前端页面实现3d模型)

前言不论是电脑桌面应用,还是Web应用,想要渲染3D模型,都需要显卡的支持。显卡越好,渲染的速度就会越快。质量就会越高。而桌面应用因为直接跟电脑显卡通信对接,使用操作系统提供的图形语言GL,...

#软件开发#(专业软件开发,小程序搭建,APP定制,网页开发)

V:18660225162公司主营APP软件开发、管理系统开发、网站建设、微信开发小程序分销商城等咨询?APP开发:安卓、苹果、h5微信纯开发、区/块/链开发、微商城搭建、办公系统、财务系统、报名系...

学会网页制作,web app开发,你需要掌握这3个编程语言

做软件开发,是从事编程开发工作,必须先从语法基础开始学习,通过语法组成产品效果。前端开发的基础语法,由HTML+CSS+JavaScript组成,这是前端开发最基本的3个语言。网页布局基础:HTML+...

前端对接微信公众号网页开发流程,前期配置

微信公众号网页开发,其实就是我们开发的h5网页需要放到微信浏览器环境中使用,但是需要对接公众号授权,授权之后可以获取到用户的个人信息,以及可以使用公众号提供的一些API,如:图片上传、图片预览、获取位...

想要搭建网页游戏平台 需要多少成本?搭建成本解析

很多人对网页游戏感兴趣,想自己搭建网页游戏平台,那么搭建的成本需要多少,具体有哪些成本呢?今天跟着99SDK小编一起来了解一下!页游平台相比其他平台不一样,页游平台的形式是一个网站,所以我们需要的成本...

网站开发中前端和后端分别是什么(网站开发中前端和后端分别是什么意思)

前端开发和后端开发是为了什么?有什么区别?通俗地说,前端工作用户可以直接看到,而后端开发工作主要在服务器端,用户无法直接看到。虽然前端开发和后端开发有很大的区别,但是为了更好的用户体验,他们的工作是相...

取消回复欢迎 发表评论: