爬取N个网页,并将其记录

挖的坑,终于能填上了,先共享出来,大家有个对比参考。也帮忙找找错误。我也正在看,看看原来是哪里出了问题。

下面这段代码已经实现了网页的爬取:

其效果为:

下面给出详细说明:

上图中出现的 __init__.py 文件,是一个空的,但是必须建立(我也没想明白为啥)。

程序结束后,打开output.html 就可以了。

1.这是网页管理模块  url_manager.py    (点击+号,看代码)

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
    def get_new_url(self):
        new_url=self.new_urls.pop()#获取并移除
        self.old_urls.add(new_url)#添加至旧的集合
        return new_url

2.这是下载网页模块   html_downloader.py

import urllib.request
class HtmlDownloader(object):

    #下载一个url里的数据
    def download(self,url):
        if url is None:
            return None
        response=urllib.request.urlopen(url)#注意py2和py3不同
        if response.getcode()!=200:#状态码200表示获取成功
            return None
        return response.read()#返回下载好的内容

3.这是网页解析模块 html_parser.py

from bs4 import BeautifulSoup
import re
import urllib.parse
#py3中urlparse在urllib中
class HtmlParser(object):

    #返回新的url集合
    def _get_new_urls(self,page_url,soup):
        new_urls=set()
        #获取所有的链接,用正则匹配
        links=soup.find_all(‘a‘,href=re.compile(r"/item/"))
        for link in links:
            new_url=link[‘href‘]#获取它的链接(不完全)
            #将不完整的new_url按照page_url的格式拼成完整的
            new_full_url=urllib.parse.urljoin(page_url,new_url)
            new_urls.add(new_full_url)
        return new_urls

    #返回对soup的解析结果
    def _get_new_data(self,page_url,soup):
        res_data={}
        #url
        res_data[‘url‘]=page_url

        #<dd class="lemmaWgt-lemmaTitle-title"><h1>Python</h1>
        #获取词条名(用了两次find)
        title_node=soup.find(‘dd‘,class_="lemmaWgt-lemmaTitle-title").find("h1")
        #注意这里先split再做join,将\\变成了\
        res_data[‘title‘]=‘\\‘.join(title_node.get_text().split(‘\\\\‘))#加入字典中

        #<div class="lemma-summary">
        #获取摘要文字
        summary_node=soup.find(‘div‘,class_="lemma-summary")
        #注意这里先split再做join,将\\变成了\
        res_data[‘summary‘]=‘\\‘.join(summary_node.get_text().split(‘\\\\‘))#加入字典中

        return res_data

    #解析一个下载好的页面的数据,并返回新的url列表和解析结果
    def parse(self,page_url,html_cont):
        if page_url is None or html_cont is None:
            return
        #创建一个bs对象(将网页字符串html_cont加载成一棵DOM树)
        soup=BeautifulSoup(html_cont,‘html.parser‘)
        new_urls=self._get_new_urls(page_url,soup)
        new_data=self._get_new_data(page_url,soup)
        return new_urls,new_data

4.下面是网页输出模块 html_outputer.py

class HtmlOutputer(object):

    def __init__(self):
        self.datas=[]

    #收集解析好的数据
    def collect_data(self,data):
        if data is None:
            return
        self.datas.append(data)

    #输出所有收集好的数据
    def output_html(self):
        with open(‘output.html‘,‘w‘) as fout:
            fout.write("<html>")
            ‘‘‘fout.write("<head>")
            fout.write("<meta  charset=\"utf-8\">")
            fout.write("</head>")‘‘‘
            fout.write("<body>")
            fout.write("<table>")
            for data in self.datas:
                fout.write("<tr>")
                fout.write("<td>%s</td>"%data[‘url‘])
                fout.write("<td>%s</td>"%data[‘title‘])
                fout.write("<td>%s</td>"%data[‘summary‘].encode(‘utf-8‘))
                fout.write("</tr>")
            fout.write("</table>")
            fout.write("</body>")
            fout.write("</html>")
            fout.close()

5.主函数,运行这个就可以了

import url_manager,html_downloader,html_parser,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#记录当前爬取的是第几个url
        self.urls.add_new_url(root_url)#先将入口url给url管理器
        #启动爬虫的循环
        while self.urls.has_new_url():#如果管理器中还有url
            try:
                new_url=self.urls.get_new_url()#就从中获取一个url
                print (‘craw %d : %s‘%(count,new_url))#打印正在爬的url
                html_cont=self.downloader.download(new_url)#然后用下载器下载它
                #调用解析器去解析这个页面的数据
                new_urls,new_data=self.parser.parse(new_url,html_cont)
                self.urls.add_new_urls(new_urls)#新得到的url补充至url管理器
                self.outputer.collect_data(new_data)#收集数据
                if count==30:#如果已经爬了30个直接退出
                    break
                count+=1
            except:
                print (‘craw failed‘)#标记这个url爬取失败
        self.outputer.output_html()#循环结束后输出收集好的数据

if __name__=="__main__":
    root_url="http://baike.baidu.com/item/Python"#入口url
    obj_spider=SpiderMain()
    obj_spider.craw(root_url)

以上内容,来自:http://blog.csdn.net/shu15121856/article/details/72903146

时间: 2024-11-03 01:32:19

爬取N个网页,并将其记录的相关文章

python网络爬虫之使用scrapy自动爬取多个网页

前面介绍的scrapy爬虫只能爬取单个网页.如果我们想爬取多个网页.比如网上的小说该如何如何操作呢.比如下面的这样的结构.是小说的第一篇.可以点击返回目录还是下一页 对应的网页代码: 我们再看进入后面章节的网页,可以看到增加了上一页 对应的网页代码: 通过对比上面的网页代码可以看到. 上一页,目录,下一页的网页代码都在<div>下的<a>元素的href里面.不同的是第一章只有2个<a>元素,从二章开始就有3个<a>元素.因此我们可以通过<div>

scrapy爬虫框架(四)-爬取多个网页

scrapy爬虫框架(四) 爬取多个网页 思路:通过判断句子控网站中,下一页是否还有a标签来获取网址,拼接后继续爬取,最终写入json文件中. juziSpider.py # -*- coding: utf-8 -*- import scrapy from juzi.items import JuziItem class JuzispiderSpider(scrapy.Spider): name = 'juziSpider' allowed_domains = ['www.juzikong.co

Python爬取一个指定网页

今天事情有点多,只能先学一点点了 import urllib.request file=urllib.request.urlopen("http://www.baidu.com") #urllib.request.urlopen调用方法并指定网页 data=file.read() #爬取所以数据 dataline=file.readline() #爬取一列数据 print(data) print(dataline) fhandle=open("C:/mymodules/1.h

小白scrapy爬虫之爬取简书网页并下载对应链接内容

*准备工作: 爬取的网址:https://www.jianshu.com/p/7353375213ab 爬取的内容:下图中python库介绍的内容列表,并将其链接的文章内容写进文本文件中 原文地址:https://www.cnblogs.com/hongdanni/p/9451868.html

Python 爬虫5——爬取并下载网页指定规格的图片

看完上篇文档之后,我们对于正则表达式已经有了基本的了解,其实学习最有效的办法就是带着问题和目的,这里我们假设有一个目标:获取某个网页上指定规格的图片的链接地址,并下载到本地. 一.实现步骤: 1.在浏览器中打开某个网页,例如:http://tieba.baidu.com/p/4691693167 2.假设我们要下载该页面中的几张大图,那么我们需要获取图片的url,这其实需要有两步操作来获取,一是先知道该图片的url,二是查看当前网页的html内容找到包含此url地址的格式,这样我们就能通过正则表

Python3批量爬取网页图片

所谓爬取其实就是获取链接的内容保存到本地.所以爬之前需要先知道要爬的链接是什么. 要爬取的页面是这个:http://findicons.com/pack/2787/beautiful_flat_icons 里面有很多不错的图标,目标就是把这些文件图片爬下来,保存成本地图片. 用python3怎么做呢? 第一步:获取要爬取的母网页的内容 import urllib.request import re url = "http://findicons.com/pack/2787/beautiful_f

c#爬取Silverlight网页

前言: 爬取普通的文本网页非常容易,但爬取Silverlight的网页代码时,有时候可能会加密.这样就会很麻烦了.下面就爬取网站http://zx.bjmemc.com.cn/ (北京空气质量网)进行说明. 任务: 网站http://zx.bjmemc.com.cn/显示的内容如下图所示.我们的任务就是将空气质量数据抓取下来. 工具: 1.fiddler,http://www.telerik.com/fiddler,一款优秀的网页请求分析工具 2.reflector,http://downloa

爬取网页

下面以爬取360浏览器网页为例,代码具有通用性,改变网页路径即可 代码如下 package 爬取网页; import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileOutputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.MalformedURLException;i

针对源代码和检查元素不一致的网页爬虫——利用Selenium、PhantomJS、bs4爬取12306的列车途径站信息

整个程序的核心难点在于上次豆瓣爬虫针对的是静态网页,源代码和检查元素内容相同:而在12306的查找搜索过程中,其网页发生变化(出现了查找到的数据),这个过程是动态的,使得我们在审查元素中能一一对应看到的表格数据没有显示在源代码中.这也是这次12306爬虫和上次豆瓣书单爬虫的最大不同点. 查找相关资料,我选择使用Selenium的PhantomJS模拟浏览器爬取源代码,这样获取到的datas包含了我需要的(查找搜索出的)途径站数据. 暂时把整个程序分为了这几个部分:(1)提取列车Code和No信息