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

一个Python小白5个小时爬虫经历前言最近业余在做一个基于.NETCore的搜索项目,奈何基层代码写好了,没有看起来很华丽的数据供测试。很巧的也是博客搜索,于是乎想到了博客园。C#也能做做页面数据抓取的,不过在博客园看到的大部分都

大家好,又见面了,我是你们的朋友全栈君。

前言

  最近业余在做一个基于.NET Core的搜索项目,奈何基层代码写好了,没有看起来很华丽的数据供测试。很巧的也是博客搜索,于是乎想到了博客园。C#也能做做页面数据抓取的,不过在博客园看到的大部分都是python实现,所以就临时想了一下看看python到底是什么东东,不看基础语法,不看语言功能,直接上代码,哪里不会搜哪里。代码完成总共用时大概4个小时,其中搭建环境加安装BeautifulSoup大概1个小时。解析HTML用时间最多了,边看demo边解析,大概2个小时,剩下的时间就是调试加保存数据了。

环境搭建

  既然用python,那么自然少不了语言环境。于是乎到官网下载了3.5版本的。安装完之后,随机选择了一个编辑器叫PyCharm,话说python编辑器还真挺多的。由于本人是小白,所以安装事项不在过多赘述。

  <span role="heading" aria-level="2">一个Python小白5个小时爬虫经历

  建好项目,打开编辑器,直接开工。本来之前用C#写的时候,大体思路就是获取网页内容,然后正则匹配。后来发现网上的帖子也很多。不过在搜索过程中发现,不建议用正则来匹配HTML。有正好我的正则不太好,所以我就搜了一下HTML解析工具,果不其然,人家都做好了,直接拿来用吧。没错就是这个东东:BeautifulSoup 。安装也很简单,不过中间出了个小插曲,就是bs4没有。继续搜,然后需要用pip安装一下就好了。(当然我并不知道ps4和pip是什么鬼)

  <span role="heading" aria-level="2">一个Python小白5个小时爬虫经历

思路分析

  博客吗,我当然就对准了博客园,于是乎,进入博客园首页,查看请求。

  <span role="heading" aria-level="2">一个Python小白5个小时爬虫经历

发送请求

  当然我不知道python是怎么进行网络请求的,其中还有什么2.0和3.0的不同,中间曲曲折折了不少,最终还是写出了最简单的一段请求代码。

  

import urllib.parse
import urllib.request

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

#获取数据
def requestCnblogs(index):
    print('请求数据')
    url = 'http://www.cnblogs.com/mvc/AggSite/PostList.aspx'
    value= {
         'CategoryId':808,
         'CategoryType' : 'SiteHome',
         'ItemListActionName' :'PostList',
         'PageIndex' : index,
         'ParentCategoryId' : 0,
        'TotalPostCount' : 4000
    }
    result = getHtml(url,value)
    return result

  其实博客园这个请求还是挺标准的,哈哈正好适合抓取。因为他返回的就是一段html。(如果返回json那不是更好。。。。)

数据解析

  上文已经提到了,用到的是BeautifulSoup,好处就是不用自己写正则,只要根据他的语法来写就好了,在多次的测试之后终于完成了数据的解析。先上一段HTML。然后在对应下面的代码,也许看起来更轻松一些。

<div class="post_item"> <div class="digg"> <div class="diggit" onclick="DiggPost('hyper-xl',6417741,281238,1)"> <span class="diggnum" id="digg_count_6417741">1</span> </div> <div class="clear"></div> <div id="digg_tip_6417741" class="digg_tip"></div> </div> <div class="post_item_body"> <h3><a class="titlelnk" href="http://www.cnblogs.com/hyper-xl/p/6417741.html" target="_blank">Python 字符串格式化</a></h3> <p class="post_item_summary"> <a href="http://www.cnblogs.com/hyper-xl/" target="_blank"> <img width="48" height="48" class="pfs" src="//pic.cnblogs.com/face/795666/20160421231717.png" alt="" /> </a> 转载请注明出处 Python2.6+ 增加了str.format函数,用来代替原有的'%'操作符 。它使用比'%'更加直观、灵活。下面详细介绍一下它的使用方法。 下面是使用'%'的例子: 格式很像C语言的printf是不是?由于'%'是一个操作符,只能在左右 两边各放一个参数,因此右边多个值需要用元组或 ... </p> <div class="post_item_foot"> <a href="http://www.cnblogs.com/hyper-xl/" class="lightblue">新月的力量_141</a> 发布于 2017-02-19 23:07 <span class="article_comment"> <a href="http://www.cnblogs.com/hyper-xl/p/6417741.html#commentform" title="" class="gray"> 评论(0) </a> </span> <span class="article_view"> <a href="http://www.cnblogs.com/hyper-xl/p/6417741.html" class="gray"> 阅读 (138) </a> </span> </div> </div> <div class="clear"></div> </div>

  通过上文的HTML代码可以看到几点。首先每一条数据都在 div(class=”post_item”)下。然后 div(“post_item_body”)下有用户信息,标题,链接,简介等信息。逐一根据样式解析即可。代码如下:

from bs4 import BeautifulSoup import request import re #解析最外层 def blogParser(index): cnblogs = request.requestCnblogs(index) soup = BeautifulSoup(cnblogs, 'html.parser') all_div = soup.find_all('div', attrs={'class': 'post_item_body'}, limit=20) blogs = [] #循环div获取详细信息 for item in all_div: blog = analyzeBlog(item) blogs.append(blog) return blogs #解析每一条数据 def analyzeBlog(item): result = {} a_title = find_all(item,'a','titlelnk') if a_title is not None: # 博客标题 result["title"] = a_title[0].string # 博客链接 result["href"] = a_title[0]['href'] p_summary = find_all(item,'p','post_item_summary') if p_summary is not None: # 简介 result["summary"] = p_summary[0].text footers = find_all(item,'div','post_item_foot') footer = footers[0] # 作者 result["author"] = footer.a.string # 作者url result["author_url"] = footer.a['href'] str = footer.text time = re.findall(r"发布于 .+? .+? ", str) result["create_time"] = time[0].replace('发布于 ','') comment_str = find_all(footer,'span','article_comment')[0].a.string result["comment_num"] = re.search(r'\d+', comment_str).group() view_str = find_all(footer,'span','article_view')[0].a.string result["view_num"] = re.search(r'\d+', view_str).group() return result def find_all(item,attr,c): return item.find_all(attr,attrs={'class':c},limit=1)

  上边一堆代码下来,着实花费了我不少时间,边写边调试,边百度~~不过还好最终还是出来了。等数据都整理好之后,然后我把它保存到了txt文件里面,以供其他语言来处理。本来想写个put直接put到ElasticSearch中,奈何没成功。后边在试吧,毕竟我的重点只是导数据,不在抓取这里。

import match import os import datetime import json def writeToTxt(list_name,file_path): try: #这里直接write item 即可,不要自己给序列化在写入,会导致json格式不正确的问题 fp = open(file_path,"w+",encoding='utf-8') l = len(list_name) i = 0 fp.write('[') for item in list_name: fp.write(item) if i<l-1: fp.write(',\n') i += 1 fp.write(']') fp.close() except IOError: print("fail to open file") #def getStr(item): # return json.dumps(item).replace('\'','\"')+',\n' def saveBlogs(): for i in range(1,2): print('request for '+str(i)+'...') blogs = match.blogParser(i,5) #保存到文件 path = createFile() writeToTxt(blogs,path+'/blog_'+ str(i) +'.json') print(''+ str(i) +'页已经完成') return 'success' def createFile(): date = datetime.datetime.now().strftime('%Y-%m-%d') path = '/'+date if os.path.exists(path): return path else: os.mkdir(path) return path result = saveBlogs() print(result)

 

  上边呢,我取了一百页的数据,也就是大概2000条做测试。

成果验收

  废了好大劲终于写完那些代码之后呢,就可以享受胜利的果实了,虽然是初学者,代码写的很渣,这参考一下,那参考一下,不过还是有些收获的。运行效果如下:

  <span role="heading" aria-level="2">一个Python小白5个小时爬虫经历

  生成的文件:

  <span role="heading" aria-level="2">一个Python小白5个小时爬虫经历

  文件内容:

  <span role="heading" aria-level="2">一个Python小白5个小时爬虫经历

总结

  一个简单的抓取程序就写完了,python还真是TM的好用。以后有空再研究研究吧。代码行数算上空行和注释总共 100 (50+25+25) 行。凑个整数好看点~~现在认识字我感觉就可以上手写程序了。这里百度一下,那里google一下,问题就解决了,程序也出来了,大功告成。

  是时候该和python暂时告别了,继续我的.NET事业。话说上次做rss采集的时候,好多“.NET要完蛋了”,“为什么我们不招.NET” 是什么鬼。 小伙伴们,下次见。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/155867.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • mnist数据集百度云链接「建议收藏」

    因为下载这个mnist实在是慢,所以我直接附上下载好的百度云链接包括下图中的内容mnist_data.rarmnist_test.csvmnist_test_10.csvmnist_train.csvmnist_train_100.csv链接:链接:https://pan.baidu.com/s/1V0WzUYvObLRU2wv8fYEwAg提取码:z9bh复制这段内容后打开…

  • 90后的我们越长大越孤单

    90后的我们越长大越孤单

  • Java安全之Unsafe类

    Java安全之Unsafe类0x00前言前面使用到的一些JNI编程和Javaagent等技术,其实在安全里面的运用非常的有趣和微妙,这个已经说过很多次。后面还会发现一些比较有意思的技术,比如AS

    2021年12月12日
  • luaJIT指令集介绍[通俗易懂]

    luaJIT指令集介绍[通俗易懂]luaJIT指令集介绍—————-目录—————(a)相关ByteCode定义介绍(b)lj_bc.h和lj_bc.c(1)字节码format简介(2)操作数的相关范围定义,和部分定义常量(3)通过掩码镜像,来获取相对应区域的值(4)通过掩码镜像,来设置相对应区域的值(5)合成实现操作符(6)关于字节码指令的定义

  • usb调试授权窗口出不来_usb调试是什么意思

    usb调试授权窗口出不来_usb调试是什么意思前段时间在玩Vysor这个Chrome扩展时遇到的一个问题:就是我在Chrome安装了Vysor扩展,但是Vysor跟我的手机老是连不上,提示我要开USB调试模式,但我的手机USB调试模式早已经打开,而且也选过“永久性授权”。-关闭USB调试再开也不行-更改连接方式也不行(MTP/PTP)-断开跟PC链接,然后撤销所有授权,再连上PC,也不见有弹出“USB调试…

  • 云计算基础之如何学习云计算?

    背景随着云计算的普及,越来越多IDC上的网站与应用开始在云上。那么同时对于我们这些IT从业者来说,也面临着加快学习云计算,不被新技术淘汰的挑战。2011年,云计算正式开始发展。今年是2018年了,是云计算发展的第7个年头了。虽然云计算的前景很好,但它的发展也更多地是在商业应用上,还没能达到学习交流分享的层次。云计算的学习路线、书籍、社区与成熟的嵌入式、互联网行业相比,是非常欠缺的!我们这次…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号