如何在50行以下的Python代码中创建Web爬虫

有兴趣了解Google,Bing或Yahoo的工作方式吗?想知道抓取网络需要什么,以及简单的网络抓取工具是什么样的?在不到50行的Python(版本3)代码中,这是一个简单的Web爬虫!(带有注释的完整源代码位于本文的底部)。

image

让我们看看它是如何运行的。请注意,您输入起始网站,要查找的单词以及要搜索的最大页数。

image

好的,但它是如何运作的?

我们先来谈谈网络爬虫的目的是什么。如维基百科页面所述,网络爬虫是一种以有条不紊的方式浏览万维网以收集信息的程序。网络爬虫收集哪些信息?通常有两件事:

  • 网页内容页面上的文字和多媒体)
  • 链接(在同一网站上的其他网页,或完全与其他网站)

这正是这个小“机器人”所做的。它从你输入spider()函数的网站开始,查看该网站上的所有内容。这个特殊的机器人不检查任何多媒体,而只是寻找代码中描述的“text / html”。每次访问网页时网页 它收集两组数据:所有的文本页面上,所有的链接页面上。如果在页面上的文本中找不到该单词,则机器人将获取其集合中的下一个链接并重复该过程,再次收集下一页上的文本和链接集。一次又一次地重复这个过程,直到机器人找到了这个单词或者已经进入了你在spider()函数中输入的限制。

这是谷歌的工作方式吗?

有点。Google有一整套网络抓取工具不断抓取网络,抓取是发现新内容的重要组成部分(或与不断变化或添加新内容的网站保持同步)。但是你可能注意到这个搜索需要一段时间才能完成,可能需要几秒钟。对于更难搜索的单词,可能需要更长时间。搜索引擎的另一个重要组成部分是索引。索引是您对Web爬网程序收集的所有数据执行的操作。索引意味着您解析(浏览和分析)网页内容并创建一个易于访问且可快速检索 *的大型集合(思考数据库或表)信息。因此,当您访问Google并输入“kitty cat”时,您的搜索词将直接到已经被抓取,解析和分析的数据集合。事实上,你的搜索结果已经坐在那里等待“小猫咪”的一个神奇短语来释放它们。这就是为什么你可以在0.14秒内获得超过1400万的结果。

*您的搜索条件实际上同时访问了许多数据库,例如拼写检查程序,翻译服务,分析和跟踪服务器等。

让我们更详细地看一下代码吧!

以下代码应完全适用于Python 3.x. 它是在2011年9月使用Python 3.2.2编写和测试的。继续将其复制并粘贴到您的Python IDE中并运行或修改它!

from html.parser import HTMLParser  
from urllib.request import urlopen  
from urllib import parse

# We are going to create a class called LinkParser that inherits some
# methods from HTMLParser which is why it is passed into the definition
class LinkParser(HTMLParser):

    # This is a function that HTMLParser normally has
    # but we are adding some functionality to it
    def handle_starttag(self, tag, attrs):
        # We are looking for the begining of a link. Links normally look
        # like <a href="www.someurl.com"></a>
        if tag == 'a':
            for (key, value) in attrs:
                if key == 'href':
                    # We are grabbing the new URL. We are also adding the
                    # base URL to it. For example:
                    # www.netinstructions.com is the base and
                    # somepage.html is the new URL (a relative URL)
                    #
                    # We combine a relative URL with the base URL to create
                    # an absolute URL like:
                    # www.netinstructions.com/somepage.html
                    newUrl = parse.urljoin(self.baseUrl, value)
                    # And add it to our colection of links:
                    self.links = self.links + [newUrl]

    # This is a new function that we are creating to get links
    # that our spider() function will call
    def getLinks(self, url):
        self.links = []
        # Remember the base URL which will be important when creating
        # absolute URLs
        self.baseUrl = url
        # Use the urlopen function from the standard Python 3 library
        response = urlopen(url)
        # Make sure that we are looking at HTML and not other things that
        # are floating around on the internet (such as
        # JavaScript files, CSS, or .PDFs for example)
        if response.getheader('Content-Type')=='text/html':
            htmlBytes = response.read()
            # Note that feed() handles Strings well, but not bytes
            # (A change from Python 2.x to Python 3.x)
            htmlString = htmlBytes.decode("utf-8")
            self.feed(htmlString)
            return htmlString, self.links
        else:
            return "",[]

# And finally here is our spider. It takes in an URL, a word to find,
# and the number of pages to search through before giving up
def spider(url, word, maxPages):  
    pagesToVisit = [url]
    numberVisited = 0
    foundWord = False
    # The main loop. Create a LinkParser and get all the links on the page.
    # Also search the page for the word or string
    # In our getLinks function we return the web page
    # (this is useful for searching for the word)
    # and we return a set of links from that web page
    # (this is useful for where to go next)
    while numberVisited < maxPages and pagesToVisit != [] and not foundWord:
        numberVisited = numberVisited +1
        # Start from the beginning of our collection of pages to visit:
        url = pagesToVisit[0]
        pagesToVisit = pagesToVisit[1:]
        try:
            print(numberVisited, "Visiting:", url)
            parser = LinkParser()
            data, links = parser.getLinks(url)
            if data.find(word)>-1:
                foundWord = True
                # Add the pages that we visited to the end of our collection
                # of pages to visit:
                pagesToVisit = pagesToVisit + links
                print(" **Success!**")
        except:
            print(" **Failed!**")
    if foundWord:
        print("The word", word, "was found at", url)
    else:
        print("Word never found")

好神奇!

进一步阅读

2014年12月,我写了一篇关于使用Java制作网络爬虫的指南,并在2015年11月,我写了一篇关于在Node.js / Javascript中制作网络爬虫的指南。如果您有兴趣了解如何使用其他语言,请查看这些内容。

原文:http://www.netinstructions.com/how-to-make-a-web-crawler-in-under-50-lines-of-python-code/ 作者: Stephen

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏蓝天

disuz 7.2文字常量定义文件messages.lang.php

D:\hadoop\backup\20120619221410\templates\default\messages.lang.php

12530
来自专栏美团技术团队

【美团技术团队博客】序列化和反序列化

摘要 序列化和反序列化几乎是工程师们每天都要面对的事情,但是要精确掌握这两个概念并不容易:一方面,它们往往作为框架的一部分出现而湮没在框架之中;另一方面,它们...

60390
来自专栏Linyb极客之路

框架设计原则

说说我的理解。这里其实是从框架结构的解读来解读,这里的包指的是 Maven 的 module。

10530
来自专栏Python中文社区

用Python实现微信接口(二)

專 欄 ❈爱撒谎的男孩,Python中文社区专栏作者 博客:https://chenjiabing666.github.io ❈ 群消息 增加了三个键值,如下...

1.4K80
来自专栏码匠的流水账

lamport面包店算法简介

Lamport面包店算法是解决多个线程并发访问一个共享的单用户资源的互斥问题的算法。由莱斯利·兰波特发明。

14330
来自专栏腾讯NEXT学位

《Node.js在CLI下的工程化体系实践》成都OSC源创会分享总结

14120
来自专栏Python学习心得

​Python爬虫--- 1.5 爬虫实践: 获取百度贴吧内容

原文链接:https://www.fkomm.cn/article/2018/7/22/21.html

12200
来自专栏轮子工厂

1. C语言的第一个程序

(。・∀・)ノ゙嗨!大家好,我是呆博~很开心可以在这里给大家分享我的 C 语言学习笔记~

21740
来自专栏Java架构

Java 10正式发布,最新特性全解读

19340
来自专栏SeanCheney的专栏

深入理解Python异步编程(上)

彻底理解异步编程是什么、为什么、怎么样。深入学习asyncio的基本原理和原型,了解生成器、协程在Python异步编程中是如何发展的。

85120

扫码关注云+社区

领取腾讯云代金券