• 利用Python编写网络爬虫下载文章


    #coding: utf-8
    #title..href...
    str0='blabla<a title="《论电影的七个元素》——关于我对电影的一些看法以及《后会无期》的一些消息" target="_blank" href="http://blog.sina.com.cn/s/blog_4701280b0102eo83.html">《论电影的七个元素》——关于我对电…</a>'
    import urllib.request
    import time
    url=['']*350
    page=1
    link=1
    while page<=7:
        con=urllib.request.urlopen('http://blog.sina.com.cn/s/articlelist_1191258123_0_'+str(page)+'.html').read().decode('utf-8')
        #print('con',con)
        title=con.find(r'<a title=')
        href=con.find(r'href=',title)
        html=con.find(r'.html',href)
        i=0
        while i<=50 and title!=-1 and href!=-1 and html!=-1: #没找到时返回-1
            url[page*50-50+i]=con[href+6:html+5]
            #print('con',con)
            title=con.find(r'<a title=',html)
            href=con.find(r'href=',title)
            html=con.find(r'.html',href)
            print(link,'.',url[page*50-50+i])
            i=i+1
            link=link+1
        else:
            print('one page find end!')
        page=page+1
    else:
        print('all pages find end')
    
    j=0
    while j<350:
        content=urllib.request.urlopen(url[j]).read().decode('utf-8')
        open(r'hanhan/'+url[j][-26:],'w+').write(content)
        print('donwloading ',j,' page:',url[j])
        j=j+1
        time.sleep(0.1)
    else:    
        print('download article finished')
        
    #r 以只读方式打开文件,该文件必须存在。
    #r+ 以可读写方式打开文件,该文件必须存在。
    #rb+ 读写打开一个二进制文件,允许读写数据,文件必须存在。
    #w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
    #w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
    #a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
    #a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)
    #wb 只写打开或新建一个二进制文件;只允许写数据。
    #wb+ 读写打开或建立一个二进制文件,允许读和写。
    #ab+ 读写打开一个二进制文件,允许读或在文件末追加数据。
    #at+ 打开一个叫string的文件,a表示append,就是说写入处理的时候是接着原来文件已有内容写入,不是从头写入覆盖掉,t表示打开文件的类型是文本文件,+号表示对文件既可以读也可以写。
    
    #二进制和文本模式的区别
    #1.在windows系统中,文本模式下,文件以"
    "代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"
    "时,函数会自动在"
    "前面加上"
    "。即实际写入文件的是"
    " 。
    #2.在类Unix/Linux系统中文本模式下,文件以"
    "代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。
    
    #打开方式总结:各种打开方式主要有三个方面的区别:
    ##①打开是否为二进制文件,用“b”标识。
    #②读写的方式,有以下几种:只读、只写、读写、追加只写、追加读写这几种方式。
    #③对文件是否必须存在、以及存在时是清空还是追加会有不同的响应。具体判断如下图。
        
    #print('---------------------test---------------------')
    #title=str0.find(r'<a title')
    #print(title)
    #href=str0.find(r'href')
    #print(href)
    #html=str0.find(r'.html')
    #print(html)
    #url=str0[href+6:html+5]
    #print(url)
    #content=urllib.request.urlopen(url).read()
    #print(content)
    #filename=url[-26:] #URL最后字符串作为文件名
    #print(filename)
    #open(filename,'wb').write(content)#把读到的内容写入到本地文件中
    今天来讲如何利用Python爬虫下载文章,拿韩寒的博客为例来一步一步进行详细探讨。。。
     
    韩寒的博客地址是:http://blog.sina.com.cn/s/articlelist_1191258123_0_1.html
     
    可以看出左边是文章列表,而且不止一页,我们先从最简单的开始,先对一篇文章进行下载,再研究对一页所有的文
    章进行下载,最后再研究对所有的文章下载。
     
     
    第一步:对一篇文章下载
     
        我们打开韩寒的博客,然后查看源码,可以看出每一篇文章的列表源码为:
        <span class="atc_title"><a title="东望洋" target="_blank"  
        href="http://blog.sina.com.cn/s/blog_4701280b0102eck1.html">东望洋</a></span>
     
        我们主要是想提取出中间绿色部分的URL,然后找到这篇文章的正文进行分析,然后提取进行下载。首先,假
        设已经得到这个字符串,然后研究如何提取这个URL,观察发现,对于所有的这类字符串,都有一个共同点,那
        就是都含有子串'<a title=''href=''.html',那么我们可以用最笨的方式---查找子串进行定界。
     
        在Python中有一个方法叫做find(),是用来查找子串的,返回子串出现的位置,那么,可以用如下代码来提
        取URL,并读取文件和下载文件。
     
    [python] view plaincopy在CODE上查看代码片派生到我的代码片
    #encoding:utf-8  
    import urllib2  
      
    def getURL(str):  
        start = str.find(r'href=')  
        start += 6  
        end   = str.find(r'.html')  
        end   += 5  
        url = str[start : end]  
        return url  
      
    def getContext(url):  
        text =urllib2.urlopen(url).read()  
        return text  
      
    def StoreContext(url):  
        content  = getContext(url)  
        filename = url[-20:]  
        open(filename, 'w').write(content)  
      
    if __name__ == '__main__':  
        str = '<span class="atc_title"><a title="东望洋" target="_blank" href="http://blog.sina.com.cn/s/blog_4701280b0102eck1.html">东望洋</a></span>'     
        url = getURL(str)  
        StoreContext(url)  
    
     
     
    第二,三步:下载所有的文章
       
        在这一步中,我们要提取第一页所有的文章的URL和标题,不再采用上面第一步的find()函数,毕竟这个函数
        缺乏灵活性,那么采用正则表达式最好。
     
        首先采集数据,观察发现,所有文章的URL都符合
     
        <a title="..." target="_blank" href="http://blog.sina.com.cn....html">
     
        这一规则,所以我们可以设置正则表达式
     
        r'<a title=".+" target="_blank" href="(http://blog.sina.com.cn.+.html)">'
     
          这样就容易了,下面是爬取韩寒所有文章,并在本地保存为.html文件。
     
    代码:
    [python] view plaincopy在CODE上查看代码片派生到我的代码片
    #coding:utf-8  
    import re  
    import urllib2  
      
    def getPageURLs(url):  
        text = urllib2.urlopen(url).read()  
        pattern = r'<a title=".+" target="_blank" href="(http://blog.sina.com.cn.+.html)">'  
        regex = re.compile(pattern)  
        urlList = re.findall(regex,text)  
        return urlList  
      
    def getStore(cnt,url):  
        text = urllib2.urlopen(url)  
        context = text.read();  
        text.close()  
        filename = 'HanhanArticle/'+str(cnt) + '.html'  
        f = open(filename,'w')  
        f.write(context)  
        f.close()  
          
    def getAllURLs():  
        urls = []  
        cnt = 0  
        for i in xrange(1,8):  
            urls.append('http://blog.sina.com.cn/s/articlelist_1191258123_0_'+str(i)+'.html')  
        for url in urls:  
            tmp = getPageURLs(url)  
            for i in tmp:  
                cnt += 1  
                getStore(cnt,i)  
          
    if __name__ == '__main__':  
        getAllURLs()  
    
     
    由于我把文章的标题用一个数字来命名,似乎不是很完美,还有两个问题没有解决,怎么提取文章的标题?,这是涉
    及到中文提取,怎么把文章的内容提取出来保存为txt格式的文件?
     
    如果能解决上面的两个问题,那么才算是真正地用网络爬虫技术实现了对韩寒博客的下载。
     
     
    (1)提取文章的标题
     
       为了方便操作,我们用BeautifulSoup来分析网页,对html文本我们提取title之间的内容为
     
        <title>东望洋_韩寒_新浪博客</title>
     
       对这个强制转化为字符串,然后进行切片操作,大致取string[7 : -28],得到了文章的标题。
    [python] view plaincopy在CODE上查看代码片派生到我的代码片
    from bs4 import BeautifulSoup  
    import re  
      
    for i in xrange(1,317):  
        filename = 'HanhanArticle/' + str(i) + '.html'  
        html = open(filename,'r')  
        soup = BeautifulSoup(html)  
        html.close()  
        title = soup.find('title')  
        string = str(title)  
        article = string[7 : -28].decode('utf-8')  
        if article[0] != '.':  
            print article  
    
     
    但是有些标题直接的内容还需要处理,比如&lt;&lt;ONE IS ALL&gt;&gt;,本来应该解释为《ONE IS ALL》
    还有比如中央电视台很*很**,这里的**在文件中不能作为名称字符。
    [python] view plaincopy在CODE上查看代码片派生到我的代码片
    #coding:utf-8  
    import re  
    import urllib2  
    from bs4 import BeautifulSoup  
      
    def getPageURLs(url):  
        text = urllib2.urlopen(url).read()  
        pattern = r'<a title=".+" target="_blank" href="(http://blog.sina.com.cn.+.html)">'  
        regex = re.compile(pattern)  
        urlList = re.findall(regex,text)  
        return urlList  
      
    def getStore(title,url):  
        text = urllib2.urlopen(url)  
        context = text.read();  
        text.close()  
        filename = 'HanhanArticle/'+ title + '.html'  
        f = open(filename,'w')  
        f.write(context)  
        f.close()  
      
    def getTitle(url):  
        html = urllib2.urlopen(url).read()  
        soup = BeautifulSoup(html)  
        title = soup.find('title')  
        string = str(title)  
        return string[7 : -28]  
      
    def Judge(title):  
        lens = len(title)  
        for i in xrange(0,lens):  
            if title[i] == '*':  
                return False  
        return True  
          
    def getAllURLs():  
        urls = []  
        for i in xrange(1,8):  
            urls.append('http://blog.sina.com.cn/s/articlelist_1191258123_0_'+str(i)+'.html')  
        for url in urls:  
            tmp = getPageURLs(url)  
            for i in tmp:  
                title = getTitle(i).decode('utf-8')  
                print title  
                if title[0] != '.' and Judge(title):  
                    getStore(title,i)  
          
    if __name__ == '__main__':  
        getAllURLs()  
     
    提取正文部分后续再处理。。。
  • 相关阅读:
    Java编程思想小笔记
    JAVA中的访问权限
    重写equals、hashCode
    JAVA核心技术I之接口与内部类
    JAVA核心技术I之继承
    javascript日志-array数组去重
    vue练习项目
    vue日志-axios跨域获取豆瓣api
    在vue-cli中安装scss,且可以全局引入scss的步骤
    css参考手册
  • 原文地址:https://www.cnblogs.com/timssd/p/4156425.html
Copyright © 2020-2023  润新知