临街小站

伯乐对象身高爬虫

最近在朋友的博客里看到了一篇文章,是讲伯乐在线这个网站上有一个面向对象栏目。什么是面向对象呢,面向对象是一个专门为IT单身男女服务的征友传播平台,由伯乐在线专门为程序员爱情创立的一个公益+免费活动。简单来说,网站的女用户在这个栏目组发帖子,包括自己的相关信息,以及理想的男友条件,男生们可以付出一定代价获得女用户保存在网站上的个人联系方式,看对眼的话,就去领证:)

然后呢,我这个朋友关注的点不太主流,他不用爬虫爬妹子照片,或者通过黑客攻击拿到妹子的联系方式,反而用python将所有发表的帖子当中对身高的要求给爬了..>

下面是我将他的代码改进:

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import requests
import re
import os
import sys

import time
from bs4 import BeautifulSoup

pageNum = 10 # 所有帖子总共10页
urlsFile = os.path.join(sys.path[0],'urls.txt')
# 保存帖子url的本地路径的字符串,os.path.join()知识提供文件路径拼接功能 如果想要创建文件夹 则使用os.mkdir(path)
infoNum = 0 #有效信息的总条数
num = 0 #包含敏感信息的总条数

# 获取所有帖子的url
def getUrls():
if(os.path.exists(urlsFile)):
return getUrlsFromFile()#如果本地存在数据直接从本地读取
urlList = list()
url='http://date.jobbole.com/page/1/?sort=latest'
while url:
html = requests.get(url)
pattern = "href=\"(.*?)\">.*?</a><label class=\"hide-on-480 small-domain-url\"></label>"
result = re.findall(pattern,html.text)
urlList = urlList + result
tem=(re.findall('<li id=\"pagination-next-page\"><a href=\"(.*?)\"',html.text))
if len(tem)>0:url=tem[0]
else:url=None
saveUrls(urlList) #保存到本地
return urlList

#本地读取所有帖子的url
def getUrlsFromFile():
urlList = list()
f = open(urlsFile,"r")
for line in f.readlines():
#全部读取再按行打乱 则每行是带换行符的数据,使用时 strip过滤
urlList.append(line.strip())
f.close()
return urlList

#将帖子信息存入本地文件中
def saveUrls(urlList):
f = open(urlsFile,"w")
f.write('%s' % '\n'.join(urlList))

#查询该帖子下的内容
def viewUrl(url):
global infoNum
result = ""
html = requests.get(url)
soup = BeautifulSoup(html.text,"lxml")
info = soup.find("div",{"class":"p-entry"})
info = str(info)
pattern = "对另一半的最低要求是:(.*?)<br/>"
r = re.findall(pattern,info)
if len(r)>0:#保证不会抛出异常
if (r[0]!=""):
infoNum = infoNum+ 1
result = r[0]
isAboutH(result)

#是否有涉及身高的敏感信息
def isAboutH(info):
global num
print(info)
keys=['(\d{3})','(\d\.\d\d)','(\d\.\d)']
f = open("infoH.txt","a")
for p in keys:
r = re.findall(p,info)
if(len(r)):
num = num + 1
f.write(str(r[0])+"\n")
f.close()
print(r[0])
break
f.close()
print("\n")

#读取在文件中的身高数据求平均值
def getAvarge():
numList=list()
f = open("infoH.txt","r")
for line in f.readlines():
line=line.strip()
if line!='':
#去除小数点
if line.find('.')!=-1:
line=(float(line))*100
num = float(line)
numList.append(num)
result=0.0
for num in numList:
result+=num
return result/len(numList)

urlList = getUrls()
num = 0
#每次爬去时需将上次爬虫信息清空
f = open("infoH.txt","w")
f.close()
for i in range(0,len(urlList)):
print('第'+str(i+1)+'个begin:')
viewUrl(urlList[i])
print('进度 %.2f\n' % ((i+1)/len(urlList)))
time.sleep(0.1)
print(infoNum)
print(num)

print('平均身高 %.2f' % getAvarge())

这个小玩具呢,实际上很简单,通常我在解析网页信息的时候有两种简单粗暴地选择,

  1. BeautifulSoup解析

  2. 正则表达式

由于我也没有通过具体的数值计算了解这两种方式的效率,所以我就顺意优先使用BeautifulSoup,如果一个信息通过一次简单的BS解析无法完成时,在这里我就使用Re正则表达式。

通过爬虫信息可以看出,妹子们的要求实际上没有太高,(当然可能是怕吓跑太多人555~),有150+的有效数据,而明确要求最低身高的大概80名左右,经过计算平均值在172左右,嗯,好吧,就这样。

clinjie wechat
Think about u every day