如何用最简单的Python爬虫采集整个网站

如何用最简单的Python爬虫采集整个网站,第1张

在之前的文章中Python实现“维基百科六度分隔理论“之基础爬虫,我们实现了在一个网站上随机地从一个链接到另一个链接,但是,如果我们需要系统地把整个网站按目录分类,或者要搜索网站上的每一个页面,我们该怎么办?我们需要采集整个网站,但是那是一种非常耗费内存资源的过程,尤其是处理大型网站时,比较合适的工具就是用一个数据库来存储采集的资源,之前也说过。下面来说一下怎么做。

网站地图sitemap

网站地图,又称站点地图,它就是一个页面,上面放置了网站上需要搜索引擎抓取的所有页面的链接(注:不是所有页面,一般来说是所有文章链接。大多数人在网站上找不到自己所需要的信息时,可能会将网站地图作为一种补救措施。搜索引擎蜘蛛非常喜欢网站地图。

对于SEO,网站地图的好处:

1.为搜索引擎蜘蛛提供可以浏览整个网站的链接简单的体现出网站的整体框架出来给搜索引擎看;

2.为搜索引擎蜘蛛提供一些链接,指向动态页面或者采用其他方法比较难以到达的页面;

3.作为一种潜在的着陆页面,可以为搜索流量进行优化;

4.如果访问者试图访问网站所在域内并不存在的URL,那么这个访问者就会被转到“无法找到文件”的错误页面,而网站地图可以作为该页面的“准”内容。

数据采集

采集网站数据并不难,但是需要爬虫有足够的深度。我们创建一个爬虫,递归地遍历每个网站,只收集那些网站页面上的数据。一般的比较费时间的网站采集方法从顶级页面开始(一般是网站主页),然后搜索页面上的所有链接,形成列表,再去采集到的这些链接页面,继续采集每个页面的链接形成新的列表,重复执行。

很明显,这是一个复杂度增长很快的过程。加入每个页面有10个链接,网站上有5个页面深度,如果采集整个网站,一共得采集的网页数量是105,即100000个页面。

因为网站的内链有很多都是重复的,所以为了避免重复采集,必须链接去重,在Python中,去重最常用的方法就是使用自带的set集合方法。只有“新”链接才会被采集。看一下代码实例:

from urllib.request import urlopenfrom bs4 import BeautifulSoupimport repages = set()def getLinks(pageurl):globalpageshtml= urlopen("" + pageurl)soup= BeautifulSoup(html)forlink in soup.findAll("a", href=re.compile("^(/wiki/)")):if'href' in link.attrs:iflink.attrs['href'] not in pages:#这是新页面newPage= link.attrs['href']print(newPage)pages.add(newPage)getLinks(newPage)getLinks("")

原理说明:程序执行时,用函数处理一个空URL,其实就是维基百科的主页,然后遍历首页上每个链接,并检查是否已经在全局变量集合pages里面,如果不在,就打印并添加到pages集合,然后递归处理这个链接。

递归警告:Python默认的递归限制是1000次,因为维基百科的链接浩如烟海,所以这个程序达到递归限制后就会停止。如果你不想让它停止,你可以设置一个递归计数器或者其他方法。

采集整个网站数据

为了有效使用爬虫,在用爬虫的时候我们需要在页面上做一些事情。我们来创建一个爬虫来收集页面标题、正文的第一个段落,以及编辑页面的链接(如果有的话)这些信息。

第一步,我们需要先观察网站上的页面,然后制定采集模式,通过F12(一般情况下)审查元素,即可看到页面组成。

观察维基百科页面,包括词条和非词条页面,比如隐私策略之类的页面,可以得出下面的规则:

所有的标题都是在h1→span标签里,而且页面上只有一个h1标签。

所有的正文文字都在div#bodyContent标签里,如果我们想获取第一段文字,可以用div#mw-content-text→p,除了文件页面,这个规则对所有页面都适用。

编辑链接只出现在词条页面上,如果有编辑链接,都位于li#ca-edit标签的li#ca-edit→span→a里面。

调整一下之前的代码,我们可以建立一个爬虫和数据采集的组合程序,代码如下:

import redef getLinks(pageUrl):global pageshtml = urlopen("" + pageUrl)soup = BeautifulSoup(html)try:print(soup.h1.get_text())print(soup.find(id="mw-content-text").findAll("p")[0])print(soup.find(id="ca-edit").find("span").find("a").attrs['href'])except AttributeError:print("页面缺少属性")for link in soup.findAll("a", href =re.compile("^(/wiki/)")):if 'href' in link.attrs:#这是新页面newPage = link.attrs['href']print("------------------\n"+newPage)

这个for循环和原来的采集程序基本上是一样的,因为不能确定每一页上都有所有类型的数据,所以每个打印语句都是按照数据在页面上出现的可能性从高到低排列的。

数据存储到MySQL

前面已经获取了数据,直接打印出来,查看比较麻烦,所以我们就直接存到MySQL里面吧,这里只存链接没有意义,所以我们就存储页面的标题和内容。前面我有两篇文章已经介绍过如何存储数据到MySQL,数据表是pages,这里直接给出代码:

import reimport datetimeimport randomimport pymysqlconn = pymysql.connect(host = '127.0.0.1',port = 3306, user = 'root', passwd = '19930319', db = 'wiki', charset ='utf8mb4')cur = conn.cursor()cur.execute("USE wiki")#随机数种子random.seed(datetime.datetime.now())#数据存储def store(title, content):cur.execute("INSERT INTO pages(title, content)VALUES(\"%s\", \"%s\")", (title, content))cur.connection.commit()def getLinks(articleUrl):html = urlopen("" + articleUrl)title = soup.find("h1").get_text()content =soup.find("div",{"id":"mw-content-text"}).find("p").get_text()store(title, content)returnsoup.find("div",{"id":"bodyContent"}).findAll("a",href=re.compile("^(/wiki/)((?!:).)*$"))#设置第一页links =getLinks("/wiki/Kevin_Bacon")try:while len(links)>0:newArticle = links[random.randint(0, len(links)-1)].attrs['href']print (newArticle)links = getLinks(newArticle)finally:cur.close()conn.close()

小结

今天主要讲一下Python中遍历采集一个网站的链接,方便下面的学习。

希望通过上面的操作能帮助大家。如果你有什么好的意见,建议,或者有不同的看法,我都希望你留言和我们进行交流、讨论。

从以下的五个方面去进行优化测试:

1、cpu瓶颈的话可以通过分布式的方式来解决 更多的结点去处理分发的任务就好了

2、本地带宽的瓶颈通过云服务器解决(一般都有100MB的方案提供) 定时定量的去购买使用可以节约成本(毕竟不是搜索引擎不会一直开着的)

3、目标服务器的带宽限制(基于IP的)通过跨区的服务器解决 云服务器提供商有多个机房的 分散节点所在的机房可以缓解问题 有提供动态ip的就更好了

4、目标服务器的访问限制,老渔哥提示搜一下<反爬虫>策略就差不多了解了 根据自己的编程能力来应对 给两个库投石问路 SeleniumPhantomJS 对于验证码相关的可以考虑购买服务(有外包的, 最高级别是人肉的一定可以搞定, 量要考虑一下价格不菲)真的不建议自己搞。

目标网站系统比较知名的话(discuz)可以网上搜搜 足够简单的话可以用opencv(有python绑定的版本而且跨平台) thredshold(二值化)处理颜色, eroded/dilate(腐蚀膨胀)处理噪点, findContours(查找轮廓)处理字符分割,穷举旋转和简单扭曲再匹配字库差不多就可以处理2010以前的简单二维码了(当然cpu开销还是很大的)

5、目标服务器的带宽上限限制 这么做的话你的爬虫就成了攻击了不讨论----以下内容常规的爬虫可能不会涉

网络爬虫又称网络蜘蛛、网络蚂蚁、网络机器人等,可以自动化浏览网络中的信息,当然浏览信息的时候需要按照我们制定的规则进行,这些规则我们称之为网络爬虫算法。使用Python可以很方便地编写出爬虫程序,进行互联网信息的自动化检索。


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/710653.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-08-06
下一篇2023-08-06

发表评论

登录后才能评论

评论列表(0条)

    保存