数学建模社区-数学中国

标题: 爬虫抓取信息 [打印本页]

作者: 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, \- MAnthor: yangyongzhen1 E0 p- y3 |0 \
Version: 0.0.2
- F+ w& H0 |0 B4 s  z' uDate: 2014-12-14. A3 A6 ]* n# T. x) J5 }
Language: Python2.7.5
2 y- C- R8 J0 q3 E( G/ E$ g( lEditor: 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 pprint7 P; H* P  \% x2 P6 n4 Y5 l. x* c

0 r5 U% C' a# freload(sys)' Q/ r1 e4 H4 J
sys.setdefaultencoding('utf8')
0 t! N- D. ^( m6 F2 t_DATA = []
# k+ K: y+ o( ?" zFILE_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( dclass 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( Sdef 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! Mdef 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 b3 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 += 17 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: cif __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