今夜看海吗 發表於 2017-2-20 22:13:00

一个Python小白5个小时爬虫经历

<h2>前言</h2>
<p>  最近业余在做一个基于.NET Core的搜索项目,奈何基层代码写好了,没有看起来很华丽的数据供测试。很巧的也是博客搜索,于是乎想到了博客园。C#也能做做页面数据抓取的,不过在博客园看到的大部分都是python实现,所以就临时想了一下看看python到底是什么东东,不看基础语法,不看语言功能,直接上代码,哪里不会搜哪里。代码完成总共用时大概4个小时,其中搭建环境加安装BeautifulSoup大概1个小时。解析HTML用时间最多了,边看demo边解析,大概2个小时,剩下的时间就是调试加保存数据了。</p>
<h2>环境搭建</h2>
<p>  既然用python,那么自然少不了语言环境。于是乎到官网下载了3.5版本的。安装完之后,随机选择了一个编辑器叫PyCharm,话说python编辑器还真挺多的。由于本人是小白,所以安装事项不在过多赘述。</p>
<p>  <img src="https://images2015.cnblogs.com/blog/841545/201702/841545-20170220213910773-1294235033.png" alt=""></p>
<p>  建好项目,打开编辑器,直接开工。本来之前用C#写的时候,大体思路就是获取网页内容,然后正则匹配。后来发现网上的帖子也很多。不过在搜索过程中发现,不建议用正则来匹配HTML。有正好我的正则不太好,所以我就搜了一下HTML解析工具,果不其然,人家都做好了,直接拿来用吧。没错就是这个东东:<strong>BeautifulSoup 。</strong>安装也很简单,不过中间出了个小插曲,就是bs4没有。继续搜,然后需要用pip安装一下就好了。(当然我并不知道ps4和pip是什么鬼)</p>
<p>  <img src="https://images2015.cnblogs.com/blog/841545/201702/841545-20170220214319898-3532323.png" alt=""></p>
<h2>思路分析</h2>
<p>  博客吗,我当然就对准了博客园,于是乎,进入博客园首页,查看请求。</p>
<p>  <img src="https://images2015.cnblogs.com/blog/841545/201702/841545-20170220214659476-2131481417.png" alt=""></p>
<h2>发送请求</h2>
<p>  当然我不知道python是怎么进行网络请求的,其中还有什么2.0和3.0的不同,中间曲曲折折了不少,最终还是写出了最简单的一段请求代码。</p>
<p>  </p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> urllib.parse
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> urllib.request

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> paramsCategoryId=808 CategoryType=SiteHome ItemListActionName=PostList PageIndex=3 ParentCategoryId=0 TotalPostCount=4000</span>
<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> getHtml(url,values):
    user_agent</span>=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
    headers </span>= {<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">User-Agent</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:user_agent}
    data </span>=<span style="color: rgba(0, 0, 0, 1)"> urllib.parse.urlencode(values)
    response_result </span>= urllib.request.urlopen(url+<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">?</span><span style="color: rgba(128, 0, 0, 1)">'</span>+<span style="color: rgba(0, 0, 0, 1)">data).read()
    html </span>= response_result.decode(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">utf-8</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> html

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">获取数据</span>
<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> requestCnblogs(index):
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">请求数据</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
    url </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">http://www.cnblogs.com/mvc/AggSite/PostList.aspx</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
    value</span>=<span style="color: rgba(0, 0, 0, 1)"> {
         </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">CategoryId</span><span style="color: rgba(128, 0, 0, 1)">'</span>:808<span style="color: rgba(0, 0, 0, 1)">,
         </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">CategoryType</span><span style="color: rgba(128, 0, 0, 1)">'</span> : <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">SiteHome</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
         </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">ItemListActionName</span><span style="color: rgba(128, 0, 0, 1)">'</span> :<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">PostList</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
         </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">PageIndex</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)"> : index,
         </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">ParentCategoryId</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)"> : 0,
      </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">TotalPostCount</span><span style="color: rgba(128, 0, 0, 1)">'</span> : 4000<span style="color: rgba(0, 0, 0, 1)">
    }
    result </span>=<span style="color: rgba(0, 0, 0, 1)"> getHtml(url,value)
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> result</pre>
</div>
<p>  其实博客园这个请求还是挺标准的,哈哈正好适合抓取。因为他返回的就是一段html。(如果返回json那不是更好。。。。)</p>
<h2>数据解析</h2>
<p>  上文已经提到了,用到的是BeautifulSoup,好处就是不用自己写正则,只要根据他的语法来写就好了,在多次的测试之后终于完成了数据的解析。先上一段HTML。然后在对应下面的代码,也许看起来更轻松一些。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="post_item"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="digg"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="diggit"</span><span style="color: rgba(255, 0, 0, 1)"> onclick</span><span style="color: rgba(0, 0, 255, 1)">="DiggPost('hyper-xl',6417741,281238,1)"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">span </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="diggnum"</span><span style="color: rgba(255, 0, 0, 1)"> id</span><span style="color: rgba(0, 0, 255, 1)">="digg_count_6417741"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>1<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="clear"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="digg_tip_6417741"</span><span style="color: rgba(255, 0, 0, 1)"> class</span><span style="color: rgba(0, 0, 255, 1)">="digg_tip"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="post_item_body"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">h3</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;</span><span style="color: rgba(128, 0, 0, 1)">a </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="titlelnk"</span><span style="color: rgba(255, 0, 0, 1)"> href</span><span style="color: rgba(0, 0, 255, 1)">="http://www.cnblogs.com/hyper-xl/p/6417741.html"</span><span style="color: rgba(255, 0, 0, 1)"> target</span><span style="color: rgba(0, 0, 255, 1)">="_blank"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>Python 字符串格式化<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">h3</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>


      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">p </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="post_item_summary"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">a </span><span style="color: rgba(255, 0, 0, 1)">href</span><span style="color: rgba(0, 0, 255, 1)">="http://www.cnblogs.com/hyper-xl/"</span><span style="color: rgba(255, 0, 0, 1)"> target</span><span style="color: rgba(0, 0, 255, 1)">="_blank"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
                <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">img </span><span style="color: rgba(255, 0, 0, 1)">width</span><span style="color: rgba(0, 0, 255, 1)">="48"</span><span style="color: rgba(255, 0, 0, 1)"> height</span><span style="color: rgba(0, 0, 255, 1)">="48"</span><span style="color: rgba(255, 0, 0, 1)"> class</span><span style="color: rgba(0, 0, 255, 1)">="pfs"</span><span style="color: rgba(255, 0, 0, 1)">
                     src</span><span style="color: rgba(0, 0, 255, 1)">="//pic.cnblogs.com/face/795666/20160421231717.png"</span><span style="color: rgba(255, 0, 0, 1)"> alt</span><span style="color: rgba(0, 0, 255, 1)">=""</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">    转载请注明出处 Python2.6+ 增加了str.format函数,用来代替原有的'%'操作符

            。它使用比'%'更加直观、灵活。下面详细介绍一下它的使用方法。 下面是使用'%'的例子: 格式很像C语言的printf是不是?由于'%'是一个操作符,只能在左右

            两边各放一个参数,因此右边多个值需要用元组或 ...
      </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="post_item_foot"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">a </span><span style="color: rgba(255, 0, 0, 1)">href</span><span style="color: rgba(0, 0, 255, 1)">="http://www.cnblogs.com/hyper-xl/"</span><span style="color: rgba(255, 0, 0, 1)"> class</span><span style="color: rgba(0, 0, 255, 1)">="lightblue"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>新月的力量_141<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
            发布于 2017-02-19 23:07
            </span><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">span </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="article_comment"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
                <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">a </span><span style="color: rgba(255, 0, 0, 1)">href</span><span style="color: rgba(0, 0, 255, 1)">="http://www.cnblogs.com/hyper-xl/p/6417741.html#commentform"</span><span style="color: rgba(255, 0, 0, 1)"> title</span><span style="color: rgba(0, 0, 255, 1)">=""</span><span style="color: rgba(255, 0, 0, 1)"> class</span><span style="color: rgba(0, 0, 255, 1)">="gray"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
                  评论(0)
                </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">span </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="article_view"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
                <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">a </span><span style="color: rgba(255, 0, 0, 1)">href</span><span style="color: rgba(0, 0, 255, 1)">="http://www.cnblogs.com/hyper-xl/p/6417741.html"</span><span style="color: rgba(255, 0, 0, 1)"> class</span><span style="color: rgba(0, 0, 255, 1)">="gray"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
                  阅读

                  (138)
                </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="clear"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<p>  通过上文的HTML代码可以看到几点。首先每一条数据都在 div(class="post_item")下。然后 div("post_item_body")下有用户信息,标题,链接,简介等信息。逐一根据样式解析即可。代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">from</span> bs4 <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> BeautifulSoup
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> request
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> re

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">解析最外层</span>
<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> blogParser(index):

cnblogs </span>=<span style="color: rgba(0, 0, 0, 1)"> request.requestCnblogs(index)
soup </span>= BeautifulSoup(cnblogs, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">html.parser</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
all_div </span>= soup.find_all(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(128, 0, 0, 1)">'</span>, attrs={<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">class</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">post_item_body</span><span style="color: rgba(128, 0, 0, 1)">'</span>}, limit=20<span style="color: rgba(0, 0, 0, 1)">)

blogs </span>=<span style="color: rgba(0, 0, 0, 1)"> []
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">循环div获取详细信息</span>
<span style="color: rgba(0, 0, 255, 1)">for</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> all_div:
      blog </span>=<span style="color: rgba(0, 0, 0, 1)"> analyzeBlog(item)
      blogs.append(blog)

</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> blogs

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">解析每一条数据</span>
<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> analyzeBlog(item):
    result </span>=<span style="color: rgba(0, 0, 0, 1)"> {}
    a_title </span>= find_all(item,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">titlelnk</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> a_title <span style="color: rgba(0, 0, 255, 1)">is</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> None:
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 博客标题</span>
      result[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(128, 0, 0, 1)">"</span>] =<span style="color: rgba(0, 0, 0, 1)"> a_title.string
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 博客链接</span>
      result[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">href</span><span style="color: rgba(128, 0, 0, 1)">"</span>] = a_title[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">href</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">]
    p_summary </span>= find_all(item,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">post_item_summary</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> p_summary <span style="color: rgba(0, 0, 255, 1)">is</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> None:
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 简介</span>
      result[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">summary</span><span style="color: rgba(128, 0, 0, 1)">"</span>] =<span style="color: rgba(0, 0, 0, 1)"> p_summary.text
    footers </span>= find_all(item,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">post_item_foot</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
    footer </span>=<span style="color: rgba(0, 0, 0, 1)"> footers
    </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 作者</span>
    result[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">author</span><span style="color: rgba(128, 0, 0, 1)">"</span>] =<span style="color: rgba(0, 0, 0, 1)"> footer.a.string
    </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 作者url</span>
    result[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">author_url</span><span style="color: rgba(128, 0, 0, 1)">"</span>] = footer.a[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">href</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">]
    str </span>=<span style="color: rgba(0, 0, 0, 1)"> footer.text
    time </span>= re.findall(r<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">发布于 .+? .+? </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, str)
    result[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">create_time</span><span style="color: rgba(128, 0, 0, 1)">"</span>] = time.replace(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">发布于 </span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">)

    comment_str </span>= find_all(footer,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">article_comment</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">).a.string
    result[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">comment_num</span><span style="color: rgba(128, 0, 0, 1)">"</span>] = re.search(r<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">\d+</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, comment_str).group()

    view_str </span>= find_all(footer,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">article_view</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">).a.string
    result[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">view_num</span><span style="color: rgba(128, 0, 0, 1)">"</span>] = re.search(r<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">\d+</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, view_str).group()

    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result

</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> find_all(item,attr,c):
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> item.find_all(attr,attrs={<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">class</span><span style="color: rgba(128, 0, 0, 1)">'</span>:c},limit=1)</pre>
</div>
<p>  上边一堆代码下来,着实花费了我不少时间,边写边调试,边百度~~不过还好最终还是出来了。等数据都整理好之后,然后我把它保存到了txt文件里面,以供其他语言来处理。本来想写个put直接put到ElasticSearch中,奈何没成功。后边在试吧,毕竟我的重点只是导数据,不在抓取这里。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> match
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> os
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> datetime
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> json

</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> writeToTxt(list_name,file_path):
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">:
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">这里直接write item 即可,不要自己给序列化在写入,会导致json格式不正确的问题</span>
      fp = open(file_path,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">w+</span><span style="color: rgba(128, 0, 0, 1)">"</span>,encoding=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">utf-8</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      l </span>=<span style="color: rgba(0, 0, 0, 1)"> len(list_name)
      i </span>=<span style="color: rgba(0, 0, 0, 1)"> 0
      fp.write(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      </span><span style="color: rgba(0, 0, 255, 1)">for</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> list_name:
            fp.write(item)
            </span><span style="color: rgba(0, 0, 255, 1)">if</span> i&lt;l-1<span style="color: rgba(0, 0, 0, 1)">:
                fp.write(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">,\n</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
            i </span>+= 1<span style="color: rgba(0, 0, 0, 1)">
      fp.write(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">]</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      fp.close()
    </span><span style="color: rgba(0, 0, 255, 1)">except</span><span style="color: rgba(0, 0, 0, 1)"> IOError:
      </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">fail to open file</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">def getStr(item):</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">   return json.dumps(item).replace('\'','\"')+',\n'</span>

<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> saveBlogs():
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> i <span style="color: rgba(0, 0, 255, 1)">in</span> range(1,2<span style="color: rgba(0, 0, 0, 1)">):
      </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">request for </span><span style="color: rgba(128, 0, 0, 1)">'</span>+str(i)+<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">...</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      blogs </span>= match.blogParser(i,5<span style="color: rgba(0, 0, 0, 1)">)
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">保存到文件</span>
      path =<span style="color: rgba(0, 0, 0, 1)"> createFile()
      writeToTxt(blogs,path</span>+<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/blog_</span><span style="color: rgba(128, 0, 0, 1)">'</span>+ str(i) +<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">.json</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">第</span><span style="color: rgba(128, 0, 0, 1)">'</span>+ str(i) +<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">页已经完成</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">success</span><span style="color: rgba(128, 0, 0, 1)">'</span>

<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> createFile():
    date </span>= datetime.datetime.now().strftime(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">%Y-%m-%d</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
    path </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/</span><span style="color: rgba(128, 0, 0, 1)">'</span>+<span style="color: rgba(0, 0, 0, 1)">date
    </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> os.path.exists(path):
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> path
    </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
      os.mkdir(path)
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> path

result </span>=<span style="color: rgba(0, 0, 0, 1)"> saveBlogs()
</span><span style="color: rgba(0, 0, 255, 1)">print</span>(result)</pre>
</div>
<p>&nbsp;</p>
<p>  上边呢,我取了一百页的数据,也就是大概2000条做测试。</p>
<h2>成果验收</h2>
<p>  废了好大劲终于写完那些代码之后呢,就可以享受胜利的果实了,虽然是初学者,代码写的很渣,这参考一下,那参考一下,不过还是有些收获的。运行效果如下:</p>
<p>  <img src="https://images2015.cnblogs.com/blog/841545/201702/841545-20170220220314054-1630216195.png" alt=""></p>
<p>  生成的文件:</p>
<p>  <img src="https://images2015.cnblogs.com/blog/841545/201702/841545-20170220220345195-15751377.png" alt=""></p>
<p>  文件内容:</p>
<p>  <img src="https://images2015.cnblogs.com/blog/841545/201702/841545-20170220220651273-701749406.png" alt=""></p>
<h2>总结</h2>
<p>  一个简单的抓取程序就写完了,python还真是TM的好用。以后有空再研究研究吧。代码行数算上空行和注释总共<strong>&nbsp;100</strong>&nbsp;(50+25+25) 行。凑个整数好看点~~现在认识字我感觉就可以上手写程序了。这里百度一下,那里google一下,问题就解决了,程序也出来了,大功告成。</p>
<p>  是时候该和python暂时告别了,继续我的.NET事业。话说上次做rss采集的时候,好多“.NET要完蛋了”,“为什么我们不招.NET” 是什么鬼。 小伙伴们,下次见。</p>
<p>&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
    多学点,总不会吃亏的。<br><br>
来源:https://www.cnblogs.com/panzi/p/6421826.html
頁: [1]
查看完整版本: 一个Python小白5个小时爬虫经历