- 在线时间
- 481 小时
- 最后登录
- 2026-8-25
- 注册时间
- 2023-7-11
- 听众数
- 4
- 收听数
- 0
- 能力
- 0 分
- 体力
- 7859 点
- 威望
- 0 点
- 阅读权限
- 255
- 积分
- 2946
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1177
- 主题
- 1192
- 精华
- 0
- 分享
- 0
- 好友
- 1
该用户从未签到
 |
#!/usr/bin/env python
: H. t2 n, F# r% D# {# Q# -*- coding:utf-8 -*-$ N; \2 P6 A, Q$ n& T, c
"""( f' ~1 q% D+ y1 u! C
Python爬虫,抓取一卡通相关企业信息; l& P! w0 r6 j6 w$ _# x/ S
Anthor: yangyongzhen
5 e. K: l- h# }- h2 G0 ?Version: 0.0.2- T* \' P2 z& s$ ?: m3 t9 l% X& p
Date: 2014-12-14
% \) g1 g/ F$ |& s+ P- @( T$ yLanguage: Python2.7.54 o# r: U! X2 q3 b! Z( {: N( W
Editor: Sublime Text2( Y: v* w; \% I9 W* u% S
"""4 l: _% j9 b U- I
& U9 M. b7 w: I! n0 J; W, T9 ]
import urllib2, re, string
2 w) U6 n! v4 Jimport threading, Queue, time" z% O2 @ c6 g
import sys
$ M, I, J# f! J p, {. \import os9 [2 v- }" I4 h t+ {+ j, ~
from bs4 import BeautifulSoup
: Q; J* X3 \* C#from pprint import pprint
/ i& v+ }& X! J6 P0 p( q+ R" z4 B: `/ z: P* F9 i# A8 }/ S
reload(sys)' b2 D- W ~* L' x: ?
sys.setdefaultencoding('utf8')
5 z+ A( V! x* ^: W% b* a! X. F8 T7 U; c/ Z_DATA = []0 o f) {$ f/ k& {
FILE_LOCK = threading.Lock()1 M& ]3 Y6 ]3 l
SHARE_Q = Queue.Queue() #构造一个不限制大小的的队列
+ e; g! Q, i; A_WORKER_THREAD_NUM = 3 #设置线程的个数6 v' N; s4 y5 N e# k& _( P
( U! {. u* h: Z; V e_Num = 0 #总条数
, I4 x+ B* r) w# F- sclass MyThread(threading.Thread) :5 b; I- n8 b$ D C. o
: e9 B4 `% r6 q+ Q) {, l, L0 U9 h def __init__(self, func,num) :
8 @( P; S9 q. D. \1 | super(MyThread, self).__init__() #调用父类的构造函数
, E4 Q- ^# l1 B) j self.func = func #传入线程函数逻辑9 F1 X- i* _: m$ }
self.thread_num = num
" w; G5 u5 n, f# E) H def run(self) :& f' x* s( S/ Y$ K& o( ?
self.func()
9 I% z: e B+ t( D! S2 e( h( z( H6 q #print u'线程ID:',self.thread_num
! R# \' U, u1 s( G; R
0 c9 c3 f X, T8 Gdef worker() :3 c! f# w: U# z6 z- {) v
global SHARE_Q$ M# S% @; y! w6 A4 y2 B- P
while not SHARE_Q.empty():1 \* U5 A. X' O( D' p ? b* Q5 \- B
url = SHARE_Q.get() #获得任务
+ q6 O, _' h4 P4 g3 z- v my_page = get_page(url)" u9 l2 O8 o# }: c' \9 z
find_data(my_page) #获得当前页面的数据
/ ?: H( {( Z- S #write_into_file(temp_data)$ f. ?; G# W% \: V* d5 i
time.sleep(1)( x$ F% H- Q" t8 n! m) J
SHARE_Q.task_done()
, A9 q( w! C ^3 e
9 c9 c, Z1 d2 qdef get_page(url) :6 o$ J* i* \2 z5 R3 L$ J: g6 n; ^& h
"""
" i* J) z; j$ F1 b 根据所给的url爬取网页HTML
5 y0 V6 r& `! B0 o+ a1 o Args:
" K- H* t+ q. C& L# _7 u2 E7 F url: 表示当前要爬取页面的url
! J6 j" s% Z* e( O4 n+ P Returns:" _0 K( [& Y9 f1 ^: @8 y
返回抓取到整个页面的HTML(unicode编码)
, `7 c1 U6 J- w Raises:: d- z! S& v+ @2 F# Z j% F
URLError:url引发的异常
9 G; R; f/ i) e) }5 V" z7 | y5 J """. C E) H5 u' S. z( U
try :, t4 E7 O( ~0 t) o# q8 ^( ]
html = urllib2.urlopen(url).read()
4 h2 l* R3 b4 |- `% ^$ ` my_page = html.decode("gbk",'ignore')
5 `2 E# C, B& D8 I2 o8 M6 c #my_page = unicode(html,'utf-8','ignore').encode('utf-8','ignore')
3 M1 l( j9 d" L" j* x$ k$ H; M/ u #my_page = urllib2.urlopen(url).read().decode("utf8")
& ^% L6 L, ~4 s except urllib2.URLError, e :4 s6 q% Y6 y2 m9 g& N6 O. }+ l
if hasattr(e, "code"):* G6 U2 S8 Y0 c6 M) {+ q0 }8 d
print "The server couldn't fulfill the request."
t5 t$ ?) f* g$ `6 [) X% W# R print "Error code: %s" % e.code+ @ T$ c0 n) q) I- n9 X# m/ H
elif hasattr(e, "reason"):* D$ C2 C' }% F6 U! t3 c. I
print "We failed to reach a server. Please check your url and read the Reason"
# F4 F; v" p; s' p7 i# D print "Reason: %s" % e.reason) I5 F2 g& T3 C7 s" E
return my_page) ?5 o( n# ]3 k& T
- c' d" \' @6 x9 j
def find_data(my_page) :3 r) A; }7 o4 f# P# Z& G" j. E
"""
# P( B% U% {! B8 l8 K$ _6 V! _ 通过返回的整个网页HTML, 正则匹配名称1 D/ F% Q- [& [' x
9 c/ H- ]& ?! ]( s7 { Args:
+ ~7 ~' m- m @5 y+ j9 l/ w" u6 ^ my_page: 传入页面的HTML文本用于正则匹配' \1 ?! E0 c% {; @5 H
"""! H& M% g" Z7 s- [
global _Num! _) k1 z/ e* S; B8 C( ?$ t# Z
temp_data = []
1 E3 y! z0 K0 W items = BeautifulSoup(my_page).find_all("div", style="width:96%;margin:10px;border-bottom:1px #CCC dashed;padding-bottom:10px;")! b# w8 u- W: Q* B
for index, item in enumerate(items) :
8 K4 D; J$ n% W2 V6 J# N2 J #print item+ B/ j4 a) C' R2 X/ ?) b
#print item.h1
* K: b6 D+ K# d #print h.group()' w) l1 _. q5 @1 T- G' \4 f' z8 z; L: p
#temp_data.append(item)8 R9 N0 q6 R; Q q/ y8 w0 p
#print item.find(re.compile("^a"))) \% E2 Y x1 E9 N
href = item.find(re.compile("^a"))
. r# r# [0 a5 S8 }: x" c #soup = BeautifulSoup(item)3 T' p1 v, o, |! `
#公司名称
+ r' W) Z' L* n0 m" t7 L4 k& [( k if item.a:
& k' z: c9 V4 a" w' p) a data = item.a.string.encode("gbk","ignore"). d/ g3 [ z& R) H
print data6 f" L8 W; y* Q, }9 q) l+ r
temp_data.append(data)3 v, c+ _6 `' X5 j8 e3 }, @# W
: _6 e# O' O, Z, o" C& v' O; x
goods = item.find_all("div", style="font-size:12px;")% o! N# ^! }- P# ?
9 w z" R8 Z8 g o
#经营产品与联系方式- Q4 |% @- g+ ^% G2 Q. _6 [# Q
for i in goods:
9 X. X7 N' A+ S( B) X& V data = i.get_text().encode("gbk","ignore")- k( n' E% d) B$ h
temp_data.append(data)/ B2 G2 w6 I( D9 D+ K# e
print data
1 R) g8 |9 D* Z, o #b = item.find_all("b")$ W J- G/ s4 n7 o; q, E2 \* o/ s
#print b6 b$ Z( z- P) u: K6 a. f
#链接地址
* H' d+ I+ `2 { pat = re.compile(r'href="([^"]*)"')
5 N: H* x2 e0 k h = pat.search(str(item))
, `, k5 ]) G( H+ ]& U) V if h:: ? _4 ?3 F* g3 n0 ], ?
#print h.group(0)0 E& x, @( A: i: P Y
href = h.group(1)1 n/ ^; k& ~9 {7 K0 G, S
print href
* n6 w2 L2 S8 \4 y5 N8 H5 A temp_data.append(h.group(1))
+ G8 v- g! R% @1 x7 s
z- N/ E" ?! V0 C3 W- H( t _Num += 1! s; F& a0 a3 X7 ]2 C7 {1 z% D
#b = item.find_all(text=re.compile("Dormouse"))% H Q" n) m% f
#pprint(goods) a* o& }5 N1 R6 ^
#print href
* w }2 P& g) Y l/ S" Q #pat = re.compile(r'title="([^"]*)"'); S" {/ s4 W/ w" m2 r6 z8 b5 c, S
#h = pat.search(str(href))
2 x- N# U# R* R9 U1 `, H) l #if h:: }/ C: F0 \! A0 b2 k3 `
#print h.group(1): }' N6 k- h% p0 H$ n4 h
#temp_data.append(h.group(1))
8 j4 R/ a; X: n9 d+ W L+ q _DATA.append(temp_data)9 s" Q# A0 w+ v/ A* w9 F
' ~8 M* A( l v% F0 v1 j#headers = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}##浏览器请求头(大部分网站没有这个请求头会报错、请务必加上哦)
6 D: f% c( C4 O/ U7 z4 j#all_url = 'http://www.mzitu.com/all' ##开始的URL地址
/ i: [$ ^5 i# M0 a2 N$ T+ H) f) h#start_html = requests.get(all_url, headers=headers) ##使用requests中的get方法来获取all_url(就是:http://www.mzitu.com/all这个地址)的内容 headers为上面设置的请求头、请务必参考requests官方文档解释* v6 x+ m; ~4 Y+ c9 ]
#print(start_html.text) ##打印出start_html (请注意,concent是二进制的数据,一般用于下载图片、视频、音频、等多媒体内容是才使用concent, 对于打印网页内容请使用text)
+ m* Z) p* N" Y( q& I' l5 [* f9 Q
1 I+ Q8 k$ {4 V9 o0 F4 N) Odef main() :
7 F2 d T6 I f* C3 U- ~) s global SHARE_Q
$ k- ?4 |) ~: m) U) T threads = []
6 F+ q3 L0 g) T7 z* V d2 G start = time.clock()9 A5 l8 M% s$ ]1 D5 M, m3 }1 ~0 T9 U
douban_url = "http://company.yktworld.com/comapny_search.asp?page={page}"1 i( ^0 \# S P: J5 E
#向队列中放入任务, 真正使用时, 应该设置为可持续的放入任务
- t$ L; y4 z& e2 I) M! H& G4 f for index in xrange(20) :
+ S: ^ n' m4 s SHARE_Q.put(douban_url.format(page = index * 1))
& q+ x v: X, c/ Z7 } for i in xrange(_WORKER_THREAD_NUM) :
+ ?0 x7 \ V) F/ ~4 t thread = MyThread(worker,i)$ P# o& b' K+ W9 c0 ?0 N6 u
thread.start() #线程开始处理任务8 Y5 T: R( J. O1 O# a5 J' ?( l7 r
8 s4 W X$ W! T) B2 Y threads.append(thread)! w" U K- t- a$ i4 Y
for thread in threads :. `( W& R; O+ }4 P7 H2 `
thread.join()- f# ]( }$ U+ k
SHARE_Q.join()
( y; V+ l5 |, x6 B/ b7 U+ T i = 0
/ e. t$ [. [9 M1 J! ` with open("down.txt", "w+") as my_file :" n% C7 S( c9 r$ ~0 F- ^
for page in _DATA :
) f8 I6 {- k/ g7 u W i += 1% ~ r' Z6 j) u: R
for name in page:
# Z3 v! P+ f# u( O2 H( } my_file.write(name + "\n")
( ?0 x- A* \# f' T! n
4 Q' a' ^! c% K; Z print "Spider Successful!!!"$ @6 o4 A3 v2 K$ K' L
end = time.clock()8 f9 n, h- P a
print u'抓取完成!'
& {! v) v# W( u" L# y- } print u'总页数:',i
. a9 ?$ N2 c+ D9 @ print u'总条数:',_Num
$ y7 z. z, H, P0 E print u'一共用时:',end-start,u'秒'8 L* B, O( x: T4 @) w1 q5 m
) |: t& c; Q% _: }0 ]+ }! T3 d& l+ K
if __name__ == '__main__':
1 I+ H) Y% R& |7 f3 p, r3 G main()
" @+ O: m9 [5 t' ~, e
& m8 i0 { F" R' E( U r% A( H. @. Y
! C' H6 T2 w0 d |
zan
|