php多线程抓取多个网页(一个IT业滚爬了多年的程序员,对这样的搜索结果很不满意)

优采云 发布时间: 2022-03-16 01:14

  php多线程抓取多个网页(一个IT业滚爬了多年的程序员,对这样的搜索结果很不满意)

  最近在长沙找工作,就通过湖南人才市场找工作。结果数据让我很难比较,作为一个在IT行业工作多年的程序员,我对这样的搜索结果很不满意。所以,我不得不自己组织数据。本文内容包括:网页数据爬取、网页数据分析、数据挖掘、python多线程、多进程应用等专题。

  先说结论

  

  首先给出上面的*敏*感*词*,从图中可以得出以下结论:

  当然,也可以挖掘出更多的有效信息。比如按薪水排名的职位:

  

  这样,我可以快速找到长沙目前的高薪职位和要求。这就是成为程序员的好处^_^。下面将介绍数据采集和数据分析。

  数据抓取

  我写了一个 crawler.py 程序。内容如下:

  # -*- coding: utf-8 -*-

import sys, os, re

import http.client

import threading

import time

ids = []

# 生成要抓取的职位列表ID

def generate_list_ids():

global ids

for i in range(1, 77):

ids.append(i)

# 生成要抓取的职位详情ID

def generate_detail_ids():

global ids

for i in range(1, 77):

f = open(str(i)+'.lst', 'r', encoding='gbk')

s = f.read(1024000)

inputs = re.findall(r"", s)

for inp in inputs:

m = re.match(r".*value='(.*)'", inp)

ids.append(m.group(1))

f.close()

# 用多线程的方式抓取,单线程太慢了

class Crawler(threading.Thread):

def __init__(self, islist=True):

self.h = http.client.HTTPConnection('www.hnrcsc.com')

self.islist = islist

threading.Thread.__init__(self)

# 抓取到的网页,将它存入文件

def write_file(self, filename):

o = open(filename, 'wb')

o.write(self.h.getresponse().read(1024000))

o.close()

# 抓取职位列表

def get_list(self, cid):

self.h.request('POST', '/Search/searchResult.asp?pagenum='+str(cid), 'flag=0&wkregion=430100&keywordtype=&postypesub=&postypemain=0100&keyword=%C7%EB%CA%E4%C8%EB%B9%D8%BC%FC%D7%D6&during=90&pagenum='+str(cid), {

'Content-Type': 'application/x-www-form-urlencoded'})

self.write_file(str(cid)+'.lst')

def get_detail(self, cid):

try:

self.h.request('GET', '/jobs/posFiles/showPosDetail.asp?posid='+str(cid))

self.write_file(str(cid)+'.det')

except:

print(cid)

self.h.close()

time.sleep(3)

self.h = http.client.HTTPConnection('www.hnrcsc.com')

def run(self):

global ids

cid = ids.pop() if len(ids)>0 else None

while cid:

if self.islist:

self.get_list(cid)

else:

self.get_detail(cid)

cid = ids.pop() if len(ids)>0 else None

print(self.name + ' Finished!')

self.h.close()

if len(sys.argv) != 2:

print('''Usage: crawler.py command

list: get list

detail: get detail

clean: clean all webpage

''')

exit()

if sys.argv[1] == 'detail': # 抓取职位详情

generate_detail_ids()

for i in range(50):

Crawler(False).start()

elif sys.argv[1] == 'list': # 抓取职位列表

generate_list_ids()

for i in range(10):

Crawler().start()

elif sys.argv[1] == 'clean': # 删除所有抓取到的文件

os.system('del *.lst')

os.system('del *.det')

else:

print('''Usage: crawler.py command

list: get list

detail: get detail

clean: clean all webpage

''')

  以上是最终程序。正如《黑客与画家》中提到的,编写程序是一个类似于绘画的过程。这是可用的半成品。我将大致描述完成这个程序的过程:

  使用http.client获取一个网页的数据,可以快速了解http.client的用法使用for循环获取2个页面的数据,测试http.client多次取数据的情况,把完成将内容放入一个方法(get_list)中,编写一个读取文件使用,并使用正则表达式提取作业详情ID的所有代码。测试通过后,注释掉这部分代码,使用http.client获取一个job details的数据,总结三个内容,就可以得到一个单线程的网页爬虫程序

  我跑了这个程序,然后出去吃饭。回来的时候看到还没写完,就看了一下python多线程的内容,改成多线程代码,加了一些容错处理。, 完成。

  数据分析

  数据分析其实就是从作业列表文件和作业明细文件中获取有效信息,放入关系数据库,然后利用关系数据库强大的查询语句,获取重要信息。数据分析的关键其实就是用正则表达式匹配关键数据部分。下面是我写的passer.py代码

<p># -*- encoding: utf-8 -*-

import re, sqlite3, multiprocessing

class Passer(multiprocessing.Process):

def __init__(self, ids, datas):

self.ids = ids

self.datas = datas

multiprocessing.Process.__init__(self)

# 获取职位详情数据

def get_detail(self, fid):

f = open(str(fid)+'.det', 'r', encoding='gbk')

s = f.read(1024000)

out = re.match(r'''.*招聘人数.*.*人&nbsp;.*/firstpage/ima/diand.gif&nbsp;&nbsp;&nbsp;&nbsp;发布日期.*(.*)&nbsp;.*.*招聘部门.*(.*)&nbsp;.*截止日期.*(.*)&nbsp;.*发布单位.*target="_blank">(.*)</a> &nbsp;.*工作方式.*(.*)&nbsp;.*最低*敏*感*词*要求.*(.*)&nbsp;.*工作地区.*(.*)&nbsp;.*薪酬待遇.*(.*)&nbsp;.*.*详细待遇.*class="zhongxia2" colspan="3" align="left" >(.*)&nbsp;.*联系电话.*(.*)&nbsp;.*电子邮件.*(.*) &nbsp;.*联 系 人.*class="zhongxia2" >(.*)&nbsp;.*通讯地址.*(.*?)&nbsp;.*岗位描述.*(.*).*岗位要求.*(.*).* ''', s, re.S)

if not out:

out = re.match(r'''.*招聘人数.*.*人&nbsp;.*/firstpage/ima/diand.gif&nbsp;&nbsp;&nbsp;&nbsp;发布日期.*(.*)&nbsp;.*.*招聘部门.*(.*)&nbsp;.*截止日期.*(.*)&nbsp;.*发布单位.*target="_blank">(.*)</a> &nbsp;.*工作方式.*(.*)&nbsp;.*最低*敏*感*词*要求.*(.*)&nbsp;.*工作地区.*(.*)&nbsp;.*详细待遇.*class="zhongxia2" colspan="3" align="left" >(.*)&nbsp;.*联系电话.*(.*)&nbsp;.*电子邮件.*(.*) &nbsp;.*联 系 人.*class="zhongxia2" >(.*)&nbsp;.*通讯地址.*(.*?)&nbsp;.*岗位描述.*(.*).*岗位要求.*(.*).* ''', s, re.S)

f.close()

return out.groups()

# 处理职位列表

def handle_file(self, fileid):

global datas

f = open(str(fileid)+'.lst', 'r', encoding='gbk')

a = re.findall('

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线