数学建模社区-数学中国
标题:
爬虫抓取信息
[打印本页]
作者:
2744557306
时间:
2024-3-31 17:18
标题:
爬虫抓取信息
#!/usr/bin/env python
% Z5 Z8 H0 [, `" Z8 j
# -*- coding:utf-8 -*-
( o r6 K1 ~, y9 S8 p) h
"""
6 D8 W/ V2 }, |1 F' ?# b
Python爬虫,抓取一卡通相关企业信息
1 c" H/ n/ O, \- M
Anthor: yangyongzhen
1 E0 p- y3 |0 \
Version: 0.0.2
- F+ w& H0 |0 B4 s z' u
Date: 2014-12-14
. A3 A6 ]* n# T. x) J5 }
Language: Python2.7.5
2 y- C- R8 J0 q3 E( G/ E$ g( l
Editor: Sublime Text2
# ?) M5 z# e4 R/ _. h+ o' K4 m2 e
"""
X! Q# d, P, t2 k; Q: L
) r2 W: E( ]" f/ p' [% S
import urllib2, re, string
: U3 N, u {! G+ f, c3 z
import threading, Queue, time
$ O0 V A* n, }
import sys
( j+ E5 w- _5 t6 z i6 ]
import os
( k7 q0 D; a! P, d6 v7 {/ M
from bs4 import BeautifulSoup
* e; _) s9 K7 b% K$ E
#from pprint import pprint
7 P; H* P \% x2 P6 n4 Y5 l. x* c
0 r5 U% C' a# f
reload(sys)
' Q/ r1 e4 H4 J
sys.setdefaultencoding('utf8')
0 t! N- D. ^( m6 F2 t
_DATA = []
# k+ K: y+ o( ?" z
FILE_LOCK = threading.Lock()
4 O" K7 l3 L) g0 P- u+ u
SHARE_Q = Queue.Queue() #构造一个不限制大小的的队列
7 i3 z, Z: j& S6 W4 P, Z
_WORKER_THREAD_NUM = 3 #设置线程的个数
% v: E3 z; V' {1 n- C
' T, h; I% ^: }: z: p. m' L+ K
_Num = 0 #总条数
9 T d0 a& r9 J/ A& R( d
class MyThread(threading.Thread) :
: H& _" f4 D, f& t: }) k
* ^. o* t3 D6 B
def __init__(self, func,num) :
" P* t9 w. ]2 v" V$ l
super(MyThread, self).__init__() #调用父类的构造函数
/ \ s( ]2 n! s4 u* t8 u
self.func = func #传入线程函数逻辑
8 B6 r+ D m6 F5 ]
self.thread_num = num
- s& n, g" J3 I4 O1 [! U/ _! d9 ]5 Q
def run(self) :
; Y# g4 a0 [$ l
self.func()
5 V; {1 P# y/ V
#print u'线程ID:',self.thread_num
( E6 q/ x! B! k1 W# D5 }2 V
0 I0 R& i: X& P7 \
def worker() :
. ?* _$ b1 e& b* E( Y
global SHARE_Q
! X; r- ^- ^; q: u9 P6 Q
while not SHARE_Q.empty():
. t7 z& S/ @) M+ @
url = SHARE_Q.get() #获得任务
r& f3 u1 j9 Z# C* J, h; p
my_page = get_page(url)
; l, ?. S. h- o& k' `0 A7 N+ W
find_data(my_page) #获得当前页面的数据
( ]* {9 ~, u k/ m
#write_into_file(temp_data)
: J2 w0 F1 r8 d: X r' W
time.sleep(1)
; `/ }. y8 f% s) o& D" H
SHARE_Q.task_done()
% ?7 H: W* F: w+ s
7 W9 C! J' w5 h" s( S
def get_page(url) :
) V' {7 k2 D" A2 H# A* Q
"""
' Y& U" F+ I- t8 I" Z1 K2 F
根据所给的url爬取网页HTML
$ g; _, A% E. N) C9 N% s( l
Args:
, n) F. J9 Z; g! M7 `
url: 表示当前要爬取页面的url
" s' ?/ c! s3 m( P% o% p! ?
Returns:
+ f4 i, t1 f. L! g% g+ }
返回抓取到整个页面的HTML(unicode编码)
`# D8 D/ p' K. N( `& t
Raises:
7 O% A/ Z o9 H. l8 r
URLError:url引发的异常
" w; w- M7 O$ v- z6 p
"""
. W5 O E, E: E
try :
( \9 g0 v* H; q
html = urllib2.urlopen(url).read()
5 h' U$ c7 }1 B& N
my_page = html.decode("gbk",'ignore')
$ S: O, N8 E, B5 N, U
#my_page = unicode(html,'utf-8','ignore').encode('utf-8','ignore')
1 K9 k0 {9 L3 p% @: I/ J
#my_page = urllib2.urlopen(url).read().decode("utf8")
% l6 y) f0 f; y+ F+ O: o! b+ S1 } F
except urllib2.URLError, e :
! b$ O! G, u8 g$ W
if hasattr(e, "code"):
1 A. Z6 h) `- K
print "The server couldn't fulfill the request."
3 @ X6 k2 x7 l! Q+ c9 F. p
print "Error code: %s" % e.code
$ o! C. \2 R0 Y+ T% t8 W
elif hasattr(e, "reason"):
4 N/ k/ {" U* T
print "We failed to reach a server. Please check your url and read the Reason"
3 V. ^0 k: O0 z" p( O& X8 w
print "Reason: %s" % e.reason
" L/ B# j, _8 w
return my_page
' E+ m+ e: g' J4 a3 F6 ^: ]
- \+ W; f9 B! M
def find_data(my_page) :
- f- S) V# g/ E8 D- d, Q& Q
"""
- S$ x: k( F3 `& A- m9 F
通过返回的整个网页HTML, 正则匹配名称
% p/ }) F+ `, a" t
% d- {7 g v$ _' S- ?
Args:
& i4 h% a/ v& c6 L: x( a2 U
my_page: 传入页面的HTML文本用于正则匹配
* S2 q5 c9 l \
"""
" B% i! Y w+ Y3 X; e" |- e! v
global _Num
* K: S& @, E; ~5 l) j1 j- {: D
temp_data = []
. z1 V7 U9 w6 u1 p) T
items = BeautifulSoup(my_page).find_all("div", style="width:96%;margin:10px;border-bottom:1px #CCC dashed;padding-bottom:10px;")
/ R4 @+ G4 Y" } \, J2 a* ]* z( w. }
for index, item in enumerate(items) :
3 F3 \/ Z w/ i1 P$ a8 |8 m& h1 i" I
#print item
( l; z, o- G1 t4 f# w& ~
#print item.h1
% O# i5 h' ]8 s @* K8 ?
#print h.group()
, g* ]1 x; s2 c3 d3 D
#temp_data.append(item)
! y, s+ |* M$ C: ?: i t6 {
#print item.find(re.compile("^a"))
6 D0 ], \/ r1 {7 {, @: O
href = item.find(re.compile("^a"))
) w7 u) m* Q, {* l
#soup = BeautifulSoup(item)
1 X1 ]: a( H! B5 i! T* h4 Y
#公司名称
) [" R0 H8 F" A Q/ k, t5 `$ v0 B. l
if item.a:
( z% ]' T$ D v7 }' [ j7 d
data = item.a.string.encode("gbk","ignore")
& _& ]; O- T) C1 U# L* P
print data
+ S% d8 b8 k) o
temp_data.append(data)
1 x+ k# K( V2 E; C
1 O; t% I5 P* ~' j
goods = item.find_all("div", style="font-size:12px;")
q7 u6 ] ~* \3 x5 {
1 Q' \) r- U$ a P- D- {( q7 `/ `
#经营产品与联系方式
$ o5 B6 e) X Y
for i in goods:
) H4 u3 N& S4 t, }) q$ q3 f5 t
data = i.get_text().encode("gbk","ignore")
* K% e1 y& ^1 h9 x' p/ k
temp_data.append(data)
- R& U# ?/ s' c* P* w
print data
$ Y8 B& D2 U2 B2 ^ M
#b = item.find_all("b")
" {. C" h0 h( X6 m( o
#print b
3 X% |/ A; L: y3 Q6 X% `4 A6 D6 g
#链接地址
. C" v4 \! I4 y! {" O0 l* F1 m
pat = re.compile(r'href="([^"]*)"')
7 B7 n+ u& V- ^7 e; J' R* G) V* g
h = pat.search(str(item))
$ \6 J" Z$ S4 M, F& N) l
if h:
4 [ n9 U3 h9 y5 T, Y/ Z: R
#print h.group(0)
2 t# O1 B$ m8 b% x5 A' X3 F$ q
href = h.group(1)
x+ T- _; L7 R0 I# e3 ?% D9 p* _3 n
print href
/ s# A0 U7 M6 l* \$ }, u9 r: a6 r
temp_data.append(h.group(1))
8 I" x k9 W( k6 d( R1 J
2 x# N+ O) c* {* S8 G$ A
_Num += 1
9 M4 A8 {/ A; h# ]3 b: h2 X
#b = item.find_all(text=re.compile("Dormouse"))
, a# k1 ?9 u" n0 m1 O+ m$ S* T1 ~% c
#pprint(goods)
8 |; a! t8 M& T) @. Y' k' Y
#print href
7 y2 \& k0 c. W R( ]
#pat = re.compile(r'title="([^"]*)"')
2 Z% g* w% A7 W' {, t) e9 M
#h = pat.search(str(href))
4 m; o# G. ^. e2 H2 C
#if h:
; u% t: s9 R a
#print h.group(1)
1 D& {$ K7 D+ m! B6 G# ?: J
#temp_data.append(h.group(1))
4 }! Q7 {3 E9 n+ @ e
_DATA.append(temp_data)
" l" ~6 |5 V, M- ^$ `$ K
" ?0 [& T" K, X! K$ b+ U, X8 l
#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"}##浏览器请求头(大部分网站没有这个请求头会报错、请务必加上哦)
2 P Q, y* [" q3 K3 Y7 y$ p) {+ w! d
#all_url = 'http://www.mzitu.com/all' ##开始的URL地址
4 N# `% w. R& A9 j8 f: w
#start_html = requests.get(all_url, headers=headers) ##使用requests中的get方法来获取all_url(就是:http://www.mzitu.com/all这个地址)的内容 headers为上面设置的请求头、请务必参考requests官方文档解释
, O2 I' |0 q( H
#print(start_html.text) ##打印出start_html (请注意,concent是二进制的数据,一般用于下载图片、视频、音频、等多媒体内容是才使用concent, 对于打印网页内容请使用text)
+ G% \! ^# B2 e4 e
! g* Z9 r% `/ w1 O" }
def main() :
! p8 D" R+ T, Y, W8 P
global SHARE_Q
+ Q* h( w. _& [4 u0 m
threads = []
0 l+ ]0 U% S w y
start = time.clock()
5 E, d5 L/ U1 q; L8 B; s- ~
douban_url = "http://company.yktworld.com/comapny_search.asp?page={page}"
, K3 |/ G" w* c1 z
#向队列中放入任务, 真正使用时, 应该设置为可持续的放入任务
- s. x8 A5 Y6 q/ p& F2 {: w
for index in xrange(20) :
$ ~4 a2 U/ H' S% J: L. g
SHARE_Q.put(douban_url.format(page = index * 1))
8 U) s9 O( U8 [
for i in xrange(_WORKER_THREAD_NUM) :
+ c' M3 Q8 Q9 B" H! O
thread = MyThread(worker,i)
" X6 A3 m5 G. _, x6 M, [
thread.start() #线程开始处理任务
/ v" X* R G( D' K7 f- _% H" ?7 X
; C v6 {2 @5 b3 s# J3 i/ ], ~; G7 |
threads.append(thread)
W0 r- D- X* y4 A2 Y, L: l7 x
for thread in threads :
! X% e' G0 O; p: s" ]# Z! e9 M
thread.join()
1 s2 B7 X1 k# |& z7 ^
SHARE_Q.join()
5 g* d, w; I' Z) q2 M
i = 0
5 j! u% j$ F* f! `6 e' }
with open("down.txt", "w+") as my_file :
, Y; b7 ]! p& S; N) C7 {0 L m2 o. I# V' H
for page in _DATA :
* I* v1 X* P8 C; }9 W* y% \3 U' O/ h
i += 1
7 M* C" c. {" c4 `' z+ @
for name in page:
; ~- D+ Q$ _! V! v" h) {- q
my_file.write(name + "\n")
: |; ?( ^$ J1 ?
2 \7 G- S% v4 J7 \
print "Spider Successful!!!"
0 T, p% ^- }" }3 f' O4 j
end = time.clock()
" t) o1 E" ]( `* p
print u'抓取完成!'
0 ?+ O% Q0 n) M8 \( }
print u'总页数:',i
% x3 r1 _( d2 U$ ?+ z K% `
print u'总条数:',_Num
% r( J/ m" v' m: n
print u'一共用时:',end-start,u'秒'
5 f. k- l' T% { ^
5 f% i! K. k$ m! V: c
if __name__ == '__main__':
! g( Y5 L( g0 ?3 J8 ]2 D
main()
4 I) e# I/ J4 J3 n
0 m. ?4 r+ h7 \
2 C) n B8 B8 |. L5 X0 ]5 i/ ?- g
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5