进入正题,描述如何实现:
    拿到一个已经有了描述的办法,实现它可以按自顶向下的思路,先将大的步骤描述出来,然后分割成小的问题,一部分一部分地解决。
    对于一个网络爬虫,如果要按广度遍历的方式下载,它就是这样干活的:
        1.从给定的入口网址把第一个网页下载下来
        2.从第一个网页中提取出所有新的网页地址,放入下载列表中
        3.按下载列表中的地址,下载所有新的网页
        4.从所有新的网页中找出没有下载过的网页地址,更新下载列表
        5.重复3、4两步,直到更新后的下载列表为空表时停止
    其实就是简化成下面的步骤:
        1.按下载列表进行下载
        2.更新下载列表
        3.循环操作1,2,直到列表为空结束

所以最初的设想就是写一个函数里面干这个:

def craw():
    while len(urlList) != 0
        Init_url_list()
        Download_list()
        Update_list()

当然,上面这个函数是工作不起来的,它只是最顶层的一个想法,底层的实现还没做。不过这一步很重要,至少让自己知道该干什么了。
    下面的事情就是将函数每一部分实现,这个可以放在一个类里去实现,我把它命名为WebCrawler。
     在python里,要按一个地址下载一个网页那并不是什么难事,你可以用urllib里的urlopen去连接上某一个网页,然后调用获取到的对象的read方法,可以得到网页的内容的字符串,像这样:

IDLE 2.6.6      ==== No Subprocess ====

>>> import urllib
>>> f = urllib.urlopen('http://www.hfut.edu.cn')
>>> s = f.read()
>>>

这样上面变量 s 里面存的就是从http://www.hfut.edu.cn这个地址里获取到的网页的内容了,是str数据类型。下面你要怎么用都可以了,把写入文件或从中提取新的地址就随你意了。当然,只要写入文件,就算下载完了这个页面。
     一个爬虫程序下载的速度肯定是很重要的问题,谁也不想用一个单线程的爬虫用一次只下一个网页速度去下载,我在学校校园网,测试了单线程的爬虫,平均每秒才 下1k。所以解决的办法只有用多线程,多开几个连接同时下载就快了。本人是Python新手,东西都是临时拿来用的。
     下载线程我是用了另外一个类,命名为CrawlerThread,它继承了threading.Thread这个类。
     因为涉及到更新下载列表的问题,线程对某个表的读写还要考虑同步,我在代码里使用了线程锁,这个用threading.Lock()构造对象。调用对象的 acquire()和release()保证每次只有一个线程对表进行操作。当然,为了保证表的更新能够实现,我使用了多个表,一个表肯定办不成。因为你 即要知道当前要下载的网络地址,还要知道你已经下载过的网络地址。你要把已经下载过的地址从新的网页中获取到的网址列表中除去,这当中又涉及了一些临时的 表。
     爬虫在下载网页的时候,最好还要把哪个网页存到了哪个文件记录好,并且记录好网页是搜索到广度搜索到的第几层的深度记录好,因为如果要做搜索引擎,这个都 是对制作索引和对网页排序有参考价值的信息。至少你自己会想知道爬虫给你下载到了什么,都放在哪了吧。对应的写记录的语句我在代码里的行末用##标注出来 了。
     写的文字已经很多了,不想再写了,直接贴上代码:

文件Test.py内容如下:(它调用了WebCrawler,运行时是运行它)
-------------------------------------------------------
-
# -*- coding: cp936 -*-
import WebCrawler

url = raw_input('设置入口url(例-->http://www.baidu.com): \n')
thNumber = int(raw_input('设置线程数:'))    #之前类型未转换出bug

wc = WebCrawler.WebCrawler(thNumber)
wc.Craw(url)

文件WebCrawler.py内容如下:
--------------------------------------------------------

# -*- coding: cp936 -*-
import threading
import GetUrl
import urllib

g_mutex = threading.Lock()
g_pages = []      #线程下载页面后,将页面内容添加到这个list中
g_dledUrl = []    #所有下载过的url
g_toDlUrl = []    #当前要下载的url
g_failedUrl = []  #下载失败的url
g_totalcount = 0  #下载过的页面数

class WebCrawler:
    def __init__(self,threadNumber):
        self.threadNumber = threadNumber
        self.threadPool = []
        self.logfile = file('#log.txt','w')                                   ##

def download(self, url, fileName):
        Cth = CrawlerThread(url, fileName)
        self.threadPool.append(Cth)
        Cth.start()

def downloadAll(self):
        global g_toDlUrl
        global g_totalcount
        i = 0
        while i < len(g_toDlUrl):
            j = 0
            while j < self.threadNumber and i + j < len(g_toDlUrl):
                g_totalcount += 1    #进入循环则下载页面数加1
                self.download(g_toDlUrl[i+j],str(g_totalcount)+'.htm')
                print 'Thread started:',i+j,'--File number = ',g_totalcount
                j += 1
            i += j
            for th in self.threadPool:
                th.join(30)     #等待线程结束,30秒超时
            self.threadPool = []    #清空线程池
        g_toDlUrl = []    #清空列表

def updateToDl(self):
        global g_toDlUrl
        global g_dledUrl
        newUrlList = []
        for s in g_pages:
            newUrlList += GetUrl.GetUrl(s)   #######GetUrl要具体实现
        g_toDlUrl = list(set(newUrlList) - set(g_dledUrl))    #提示unhashable
               
    def Craw(self,entryUrl):    #这是一个深度搜索,到g_toDlUrl为空时结束
        g_toDlUrl.append(entryUrl)
        depth = 0
        while len(g_toDlUrl) != 0:
            depth += 1
            print 'Searching depth ',depth,'...\n\n'
            self.downloadAll()
            self.updateToDl()
            content = '\n>>>Depth ' + str(depth)+':\n'                         ##(该标记表示此语句用于写文件记录)
            self.logfile.write(content)                                        ##
            i = 0                                                              ##
            while i < len(g_toDlUrl):                                          ##
                content = str(g_totalcount + i) + '->' + g_toDlUrl[i] + '\n'   ##
                self.logfile.write(content)                                    ##
                i += 1                                                         ##
        
class CrawlerThread(threading.Thread):
    def __init__(self, url, fileName):
        threading.Thread.__init__(self)
        self.url = url    #本线程下载的url
        self.fileName = fileName

def run(self):    #线程工作-->下载html页面
        global g_mutex
        global g_failedUrl
        global g_dledUrl
        try:
            f = urllib.urlopen(self.url)
            s = f.read()
            fout = file(self.fileName, 'w')
            fout.write(s)
            fout.close()
        except:
            g_mutex.acquire()    #线程锁-->锁上
            g_dledUrl.append(self.url)
            g_failedUrl.append(self.url)
            g_mutex.release()    #线程锁-->释放
            print 'Failed downloading and saving',self.url
            return None    #记着返回!
       
        g_mutex.acquire()    #线程锁-->锁上
        g_pages.append(s)
        g_dledUrl.append(self.url)
        g_mutex.release()    #线程锁-->释放

文件GetUrl.py内容如下:(它里面的GetUrl从一个存有网页内容的字符串中获取所有url并以一个list返回,这部分实现方法很多,大家可以自己写个更好的)
--------------------------------------------------------

urlSep = ['<','>','\\','(',')', r'"', ' ', '\t', '\n']
urlTag = ['http://']

def is_sep(ch):
    for c in urlSep:
        if c == ch:
            return True
    return False

def find_first_sep(i,s):
    while i < len(s):
        if is_sep(s[i]):
            return i
        i+=1
    return len(s)

def GetUrl(strPage):
    rtList = []
    for tag in urlTag:
        i = 0
        i = strPage.find(tag, i, len(strPage))
        while i != -1:
            begin = i
            end = find_first_sep(begin+len(tag),strPage)
            rtList.append(strPage[begin:end])
            i = strPage.find(tag, end, len(strPage))

return rtList

转载于:https://my.oschina.net/u/240562/blog/51592

Python实现网络爬虫相关推荐

  1. Python3网络爬虫快速入门实战解析(一小时入门 Python 3 网络爬虫)

    Python3网络爬虫快速入门实战解析(一小时入门 Python 3 网络爬虫) https://blog.csdn.net/u012662731/article/details/78537432 出 ...

  2. 网页爬虫python代码_《用python写网络爬虫》完整版+源码

    原标题:<用python写网络爬虫>完整版+源码 <用python写网络爬虫>完整版+附书源码 本书讲解了如何使用Python来编写网络爬虫程序,内容包括网络爬虫简介,从页面中 ...

  3. Python学习网络爬虫--转

    原文地址:https://github.com/lining0806/PythonSpiderNotes Python学习网络爬虫主要分3个大的版块:抓取,分析,存储 另外,比较常用的爬虫框架Scra ...

  4. Python即时网络爬虫项目: 内容提取器的定义(Python2.7版本)

    1. 项目背景 在Python即时网络爬虫项目启动说明中我们讨论一个数字:程序员浪费在调测内容提取规则上的时间太多了(见上图),从而我们发起了这个项目,把程序员从繁琐的调测规则中解放出来,投入到更高端 ...

  5. 《用Python写网络爬虫》——1.5 本章小结

    本节书摘来自异步社区<用Python写网络爬虫>一书中的第1章,第1.5节,作者 [澳]Richard Lawson(理查德 劳森),李斌 译,更多章节内容可以访问云栖社区"异步 ...

  6. Python之父推荐!《Python 3网络爬虫开发实战》第二版!文末送签名版!

    很多读者会让我写爬虫方面的书籍,我也一直没写,没写的原因主要有两个,第一个就是在爬虫方面我其实不是很擅长,第二个原因就是因为在爬虫领域庆才已经做的足够好了,我写不一定能写出庆才这水平的,所以也就一直没 ...

  7. 用Python写网络爬虫pdf

    下载地址:网盘下载 作为一种便捷地收集网上信息并从中抽取出可用信息的方式,网络爬虫技术变得越来越有用.使用Python这样的简单编程语言,你可以使用少量编程技能就可以爬取复杂的网站. <用Pyt ...

  8. python网络爬虫_python小知识,基于Python 的网络爬虫技术分析

    在现阶段大数据的时代中,想要实现对数据的获取和分析,要先具备足够的数据源,网络爬虫技术就为其数据获取提供了良好的条件,且还能够实现对数据源的目的性采集. 在网络爬虫技术应用中,Python 脚本语言的 ...

  9. 爬虫技术python流程图_基于Python的网络爬虫技术研究

    基于 Python 的网络爬虫技术研究 王碧瑶 [摘 要] 摘要:专用型的网络爬虫能够得到想要的返回结果 , 本文就以拉勾网作 为例子 , 对基于 Python 的网络爬虫技术进行研究和分析. [期刊 ...

  10. 用python写网络爬虫 第2版 pd_用Python写网络爬虫(第2版)

    用Python写网络爬虫(第2版)电子书 畅销的Python网络爬虫发实战图书全新升级版,上一版年销量近40000册. 针对Python 3.6版本编写. 提供示例完整源码和实例网站搭建源码,确保用户 ...

最新文章

  1. R语言data.table进行滚动数据连接,滚动联接通常用于分析涉及时间的数据实战(动画说明滚动数据连接的形式):rolling joins data.table in R
  2. vue前端上传文件夹的插件_基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件...
  3. php基础教程 第一步 环境配置及helloworld
  4. QT 提示之右下角冒泡
  5. java mockserver搭建_mockjs,json-server一起搭建前端通用的数据模拟框架教程
  6. 《从问题到程序:用Python学编程和计算》——2.6 简单脚本程序
  7. leetcode题库1277-- 统计全为 1 的正方形子矩阵
  8. 关于陀螺仪 deviceorientation
  9. 用linux制作Mac OS U盘启动
  10. 模2除法与二进制除法
  11. js传递参数时类型错误
  12. 【Lintcode】350. Slash Separating
  13. programming paradigm
  14. glib安装详细教程
  15. win10查看显卡的运算能力
  16. CSC公派|高职院校教师赴澳大利亚大学访学
  17. 2014全国计算机等级考试大纲,2014全国计算机等级考试大纲级.doc
  18. VUE动态切换Button的icon
  19. STM32通过PWM驱动两个直流电机
  20. Win11 + wsl2 + xfce4实现可视化ubuntu的问题

热门文章

  1. 2019 8 9 STM32F407ADS1526连续转换模式相关配置(采样率达到15000SPS)
  2. 库存遮羞布被揭开,高通提前发布骁龙8G2,国产手机已无路可走
  3. 小虾米的求助Massage
  4. 星际战一直显示网络无法连接服务器,所有战网应用均无法连接到服务器,无法登陆...
  5. 基于FPGA的任意字节数的串口发送(含源码工程)
  6. android 键盘遮挡
  7. 设置view 的MarginTop
  8. 国外广告联盟:玩转国外CPC网站作弊
  9. (十一)简单的2维机器人仿真器
  10. 红米k30pro开发者选项