python爬虫接单经历_一个Python小白5个小时爬虫经历

前言

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

环境搭建

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

65c23ba3dc06a55f818ec9bfc8b01e96.png

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

3b36ddf2d5289542890ddc537c00ea7a.png

思路分析

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

69fb6594ddfb9f42536d459a68ea47f3.png

发送请求

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

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')

returnhtml

#获取数据

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)

returnresult

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

数据解析

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

1

Python字符串格式化

src="//pic.cnblogs.com/face/795666/20160421231717.png"alt=""/>

转载请注明出处Python2.6+增加了str.format函数,用来代替原有的'%'操作符

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

两边各放一个参数,因此右边多个值需要用元组或...

新月的力量_141

发布于2017-02-1923:07

评论(0)

阅读

(138)

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

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获取详细信息

foritem inall_div:

blog=analyzeBlog(item)

blogs.append(blog)

returnblogs

#解析每一条数据

def analyzeBlog(item):

result={}

a_title=find_all(item,'a','titlelnk')

ifa_title isnotNone:

# 博客标题

result["title"]=a_title[0].string

# 博客链接

result["href"]=a_title[0]['href']

p_summary=find_all(item,'p','post_item_summary')

ifp_summary isnotNone:

# 简介

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()

returnresult

def find_all(item,attr,c):

returnitem.find_all(attr,attrs={'class':c},limit=1)

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

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('[')

foritem inlist_name:

fp.write(item)

ifi

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():

foriinrange(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

ifos.path.exists(path):

returnpath

else:

os.mkdir(path)

returnpath

result=saveBlogs()

print(result)

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

成果验收

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

1c0adc7316ffdad1dcc6049de071a7bc.png

生成的文件:

b7866d727aa55b2374ac109604022917.png

文件内容:

83bfe3b21187c2fba00459c2d52e7d89.png

总结

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值