Python什么方法可以避免重复抓取同一网页
在之前的文章中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("------------------
"+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中遍历采集一个网站的链接,方便下面的学习。
希望通过上面的操作能帮助大家。如果你有什么好的意见,建议,或者有不同的看法,我都希望你留言和我们进行交流、讨论。
你好
首先,浏览器显示给用户的内容完全是根据html源码来的、所以,你想获取的一切浏览器显示的内容,都是在html文件中存在的内容
统计页面上的单词,必然是要读html源文件的
可以使用urllib2库,以及re库来进行匹配查找,代码如下:
import urllib2import reword = '你想查找的单词'urlfile = urllib2.urlopen('你要打开的网址内容,记住要带上协议前缀,比如http') #以文件的形式打开一个网页html = urlfile.read() #从网页文件中读htmlwordList = re.findall(re.compile(word), html) #正则findall 查找所有的单词print len(wordList) #个数re模块记不太清,没试验、试试看,不行再追问
初学python编程什么方法可取?
如果能提前给自己安排好学习的计划和内容,就能很大程度的提升学习效率,达到事半功倍的效果。一个简单的办法就是给自己一个“约定”:告诉自己,每天只花30分钟来学习Python,学完之后才能看手机刷百度等。也许有的人会说,晚上熬夜写代码效率更高,其实这种想法是不可取的。因为熬夜给身体带来的伤害大家...
python是什么意思?
python本意是:巨蛇,大蟒;Python是一种跨平台的计算机程序设计语言。python是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python的创始人为荷兰人吉多·范罗苏姆(...
python进入编程界面的方法是什么
python进入编程界面的方法如下:工具\/材料:华硕VivoBook15x电脑,win10系统,Python3.9.4版本。1、在电脑搜索框中输入python进行搜索,在搜索结果中打开python编辑器。2、如果代码很少,比如只有一行的,可以在打开的编辑器中直接输入程序代码。3、如果程序代码较长的,点击“File—NewFile”新建程序窗口。
python函数和方法区别
首先,从分类的角度来分析。(1)函数的分类:内置函数:python内嵌的一些函数。匿名函数:一行代码实现一个函数功能。递归函数 自定义函数:根据自己的需求,来进行定义函数。(2)方法的分类:普通方法:直接用self调用的方法。私有方法:__函数名,只能在类中被调用的方法。属性方法:@property,将方法...
Python 里面的 函数 和 方法 怎么区分
在python里,函数在很多时候就叫方法,比如在类里面定义函数,其实就是类的方法。还有自定义函数,其实也可以称做自定义方法。不用太在意称呼,没什么区别,你知道别人说方法其实就是函数就行。反之亦然python 里面的 函数 和 方法 怎么区分
python魔法方法是什么
魔法方法是python内置方法,不需要主动调用,存在的目的是为了给python的解释器进行调用,几乎每个魔法方法都有一个对应的内置函数,或者运算符,当我们对这个对象使用这些函数或者运算符时就会调用类中的对应魔法方法,可以理解为重写这些python的内置函数。python学习网,大量的免费python视频教程,欢迎在线学习!...
python中的+有哪几种使用方法呢?
1、两个值相加,然后返回值给符号左侧的变量 举例如下:>>> a=1 >>> b=3 >>> a+=b(或者a+=3)>>> a 42、用于字符串连接(变量值带引号,数据类型为字符串)>>> a='1'>>> b='2'>>> a+=b >>> a '12'
python重复执行代码的方法有哪些呢?
```python def repeat_hello_world(n):if n > 0:print("Hello, world!")repeat_hello_world(n - 1)repeat_hello_world(10)```这段代码会重复执行10次,每次都会输出"Hello, world!",直到n的值等于0为止。以上是几种常见的重复执行代码的方法,具体应该根据实际需求选择合适的方式。
Python列表去重的六种方法
探索Python列表去重的六种高效策略<\/ 方法一:利用set的独特性质<\/ Python内置的set数据结构具有无序且不允许重复元素的特性,我们可以巧妙地利用这个特性来去重。通过将列表转换为set,再转换回list,即可实现去重,尽管set会打乱原有顺序,但这是唯一可能丢失顺序的方法<\/。方法二:借助字典的键值对<\/ ...
python方法和函数的区别
这只是在 python3 中才有的区分,python2 中全部称为方法。最大的区别是参数的传递参数,方法是自动传参self,函数是主动传参
昌美复方: 最简单的办法,不需要任何第三方库,获取网页源代码,进行正则匹配: import urllib,re url = "http://www.163.com" #网页地址 wp = urllib.urlopen(url) #打开连接 content = wp.read()
奉化市13794338830: python实现mysql插入数据时,判断是否存在,不存在就插入,重复跳过 - ?
昌美复方: 方案一:使用ignore关键字 如果是用主键primary或者唯一索引unique区分了记录的唯一性,避免重复插入记录可以使用: insert ignore into table_name(email,phone,user_id) values('test9@163.com','99999','9999'),这样当有重复记 录就会忽略...
奉化市13794338830: python 生成随机字符串 - ?
昌美复方: def getstr(n): st = '' while len(st)temp = chr(97+random.randint(0,25))if st.find(temp) == -1 :st = st.join(['',temp]) return st
奉化市13794338830: python爬虫怎么抓包 - ?
昌美复方: 方案:1. 自己通过request库手动编写2. 使用python的爬虫库scrapy 最推荐的一种:使用python的爬虫库scrapy 推荐理由:1. 应用最广泛的爬虫框架,没有之一2. 成熟度最高的框架,没有之一3. 利用成熟产品,避免重复“造轮子”,可以更快速的构建项目
奉化市13794338830: python 重载方法有哪些特点 - ?
昌美复方: python 的重载主要包括方法重载和运算符重载.1.python 方法重载: 其他的语言一般对于方法重载的话,主要是根据参数的类型不同或者是数量不同来区分同名的方法.而python则比较特殊,它本身是动态语言,方法的参数是没有类型的,当调...
奉化市13794338830: python scrapy怎么url去重 - ?
昌美复方: 建一个Url管理器,就不会重复抓取了 改成这样就可以了.1 2 3 4defstart_requests(self): yieldscrapy.Request('url', self.parse) yieldscrapy.Request('url', self.parse) yieldscrapy.Request('url', self.parse)
奉化市13794338830: Python爬虫抓取数据周期性重复,问题出在什么地方 - ?
昌美复方: 完全没有看到模拟浏览器的代码,你的情况,大概是被返爬虫机制影响.建议加上模拟post或get,模拟浏览器访问的代码.
奉化市13794338830: python有哪些方法可让list中的元素重复N次 - ?
昌美复方: 用*运算符 [1,2,3]*3 结果 [1, 2, 3, 1, 2, 3, 1, 2, 3]
奉化市13794338830: python 反复执行问题 - ?
昌美复方: 你好,time模块中的:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18Python 编程中使用 time 模块可以让程序休眠具体方法是time.sleep(秒数),其中“秒数”以秒为单位,可以是小数,0.1秒则代表休眠100毫秒. # 例1:循环输出休眠1秒 ...
奉化市13794338830: python中的列表中常用的方法有哪些,分别是什么作用? - ?
昌美复方: Python列表定义:按特定顺序排列的元素组成.在Python中,用方括号[]来表示列表,并用逗号来分隔其中的元素.Python列表是编程中很常见的数据类型 . 列表是一种可修改的集合类型,其元素可以是数字、string等基本类型,也可以是列表...