网页抓取数据百度百科(环境爬虫架构根据上面的流程,开始爬取百度百科1000个页面)

优采云 发布时间: 2021-12-04 17:31

  网页抓取数据百度百科(环境爬虫架构根据上面的流程,开始爬取百度百科1000个页面)

  环境爬虫架构

  

  按照上述流程,开始爬取百度百科1000页。

  运行过程

  非常详细的描述。

  

  我们要抓取的信息是

  

  html源码中对应的信息为:

  

  了解了获取那些信息和爬虫的基本流程,

  下面我们结合各个部分的功能来实现具体的代码。

  履带调度员

  启动爬虫,停止爬虫,或者监控爬虫的运行状态。

  我们以百度百科的python入口的url作为入口点。编写主函数。

  # coding:utf8

import url_manager, html_parser, html_downloader,html_outputer

class SpiderMain(object):

def __init__(self):

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

self.downloader = html_downloader.HtmlDownLoader() #下载器

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

self.outputer = html_outputer.HtmlOutputer() #输出器

def craw(self,root_url):

count = 1

print "count =",count

#将入口url添加进url管理器(单个)

self.urls.add_new_url(root_url)

#启动爬虫的循环

while self.urls.has_new_url():

try:

#获取待爬取的url

new_url = self.urls.get_new_url()

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

#启动下载器下载html页面

html_cont = self.downloader.download(new_url)

#解析器解析得到新的url列表以及新的数据

new_urls, new_data = self.parser.parse(new_url, html_cont)

#将获取的新的url添加进管理器(批量)

self.urls.add_new_urls(new_urls)

#收集数据

self.outputer.collect_data(new_data)

except:

print "craw failed!!!"

if count ==1000:

break

count = count + 1

#输出收集好的数据

self.outputer.output_html()

if __name__=="__main__":

#爬虫入口url

root_url = "https://baike.baidu.com/item/Python"

obj_spider = SpiderMain()

#启动爬虫

obj_spider.craw(root_url)

  网址管理器

  对要爬取的URL集合和已爬取的URL集合进行管理,目的是防止重复爬取和循环爬取。需要支持的方法:

  # -*-coding:utf8 -*-

class UrlManager(object):

def __init__(self):

self.new_urls = set()

self.old_urls = set()

#判断待爬取url是否在容器中

def add_new_url(self,url):

if url is None:

return

if url not in self.new_urls and url not in self.old_urls:

self.new_urls.add(url)

#添加新url到待爬取集合中

def add_new_urls(self,urls):

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

return

for url in urls:

self.add_new_url(url)

#判断是否还有待爬取的url

def has_new_url(self):

return len(self.new_urls)!=0

#获取待爬取url并将url从待爬取移动到已爬取

def get_new_url(self):

new_url = self.new_urls.pop()

self.old_urls.add(new_url)

return new_url

  网页下载器

  从url管理中取一个要爬取的url,下载器会下载该url指定的网页,并存储为字符串。

  这里使用python urllib2库下载网页。

  # -*- coding:utf-8

import urllib2

class HtmlDownLoader(object):

def download(self, url):

if url is None:

return None

#直接请求

response = urllib2.urlopen(url)

#获取状态码,200表示获取成功,404失败

if response.getcode() !=200:

return None

else:

return response.read() #返回获取内容

  网页解析器

  将字符串发送给网页解析器,一方面解析出有价值的数据,另一方面将网页中指向其他网页的URL补充给url管理器,形成一个循环。

  这里使用了结构化分析,BeautifuSoup使用DOM树的方式来解析网页。

  

  # -*- coding:utf-8 -*

import re

import urlparse

from bs4 import BeautifulSoup

class HtmlParser(object):

def _get_new_urls(self, page_url, soup):

print 'in parse def _get_new_urls'

#/item/xxx

new_urls = set()

links = soup.find_all('a',href=re.compile(r'/item/'))

for link in links:

new_url = link['href']

new_full_url = urlparse.urljoin(page_url, new_url)

new_urls.add(new_full_url)

return new_urls

def _get_new_data(self, page_url, soup):

res_data = {}

#url

res_data['url'] = page_url

#Python

#获取标题的标签

title_node = soup.find('dd', class_="lemmaWgt-lemmaTitle-title").find("h1")

res_data['title'] = title_node.get_text()

#

summary_node = soup.find('div', class_="lemma-summary")

res_data['summary'] = summary_node.get_text()

return res_data

def parse(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

  出口商

  需要采集数据,然后以html的形式输出数据。

  # -*-coding:utf-8 -*-

class HtmlOutputer(object):

def __init__(self):

self.data = []

def collect_data(self, data):

#print "def collect_data(self, data):"

if data is None:

return

self.data.append(data)

def output_html(self):

#print "def output_html(self):"

fout = open('output.html','w')

fout.write('')

fout.write('')

fout.write('')

#ASCII

for data in self.data:

fout.write("")

fout.write("%s" % data['url'])

fout.write("%s" % data['title'].encode('utf-8'))

fout.write("%s" % data['summary'].encode('utf-8'))

fout.write("")

fout.write('')

fout.write('')

fout.write('')

  操作结果

  

  抓取的数据

  

  总结

  这个研究是前两天的工作,后来遇到了一些关于正则表达式的问题。正则表达式在爬虫中非常重要。昨天花了一天时间系统学习python中re模块的正则表达式。,我今天刚完成。这个项目是我开始使用爬虫的实践。爬虫的重点在于三个模块:url管理器、网页下载器和网页解析器。这三者形成一个循环,实现持续爬行的信心,能力有限。还有一些细节没有很好理解,继续学习ing。

  完整代码已经上传到我的Github:

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线