http://fly5.com.cn/p/p-work/%E8%B0%B7%E6%AD%8C%E7%BD%91%E9%A1%B5%E7%9B%AE%E5%BD%95%E6%95%B0%E6%8D%AE%E6%8A%93%E5%8F%96.html
谷歌网页目录数据抓取
目标地址为:http://www.google.com/Top/World/Chinese_Simplified/ 我们要获取这些站点的keyword(网站名)、pr值、以及网址
抓取采用了 urllib2 + regex 的组合方式
数据库为mysql,使用模块 MySQLdb
分为三个文件: spider_Model.py、dbModel.py、google_list.py
如果想更改存储方式,只需自行设定 google_list.py 中的 save函数即可
废话不多说,上程序:
抓取model: spider_Model.py
这个文件预置了 手动输入验证码、生成随机数、代理抓取,便于以后用于更多用途
抓取时模拟firefox浏览器访问留下的痕迹,自带cookie管理,并且自动refer为上一次访问的页面
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 | #!/usr/bin/env python #coding=utf-8 import urllib,urllib2 import socket import cookielib import time import random,string #超时设定 socket.setdefaulttimeout(10.0) class Spider(object): def __init__(self,host='www.google.com',encode='utf-8'): self.HOST = host self.ENCODE = encode self._set_cookie() def _set_cookie(self): #加载cookie cj = cookielib.CookieJar() #proxy_support = urllib2.ProxyHandler({"http":"http://127.0.0.1:7070"}) self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) self.opener.addheaders = [("Host",self.HOST), ("User-Agent","Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.8) Gecko/20100215 Ubuntu/9.04 (jaunty) Shiretoko/3.5.8"), ("Accept","text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"), ("Accept-Language","zh-cn,zh;q=0.8"), ("Accept-Charset","GB2312,utf-8;q=0.5,*;q=0.5"), ("Keep-Alive","300"), ("Cookie","PREF=ID=5ac93d1521e08c1b:U=8260225976856014:LD=en:NR=10:CR=2:TM=1268648036:LM=1270784729:GM=1:S=iGzspMhd7z9-Xnj7; NID=33=CYN_u9CMi6tE_KN8ACu8DIgXgo4-jeHVsQ_nCDzN7UBxtDsy4-D4dEX67EB99YAYZ_S4li699CFoVWP5xPAUbIatvHLHHECWjl87-X8TZvhMZlSNKZVT_pXocx8_jo6m"), ("Connection","keep-alive")] #发送post 信息 def post(self,url,values): urllib2.install_opener(self.opener) WS_data = urllib.urlencode(values) WS_req = urllib2.Request(url,WS_data) WS_response = urllib2.urlopen(WS_req).read().decode(self.ENCODE,'ignore') return WS_response #获取网页信息 def get(self,url): urllib2.install_opener(self.opener) num = 0 while True: try: response = urllib2.urlopen(url).read().decode(self.ENCODE,'ignore') num = 0 break except: num = num + 1 if num == 1: print '*****get html error*****\nURL:%s,Num:%s' % (url,num) elif num >= 10: print num return False time.sleep(3) #设置referer self.opener.addheaders.append(('Referer',url)) #print "获取成功" # 获取发送后的返回信息 return response #获取验证码 def save_validate_code(img_code,path = '1.bmp'): f = open(path,"wb") f.write(img_code) f.close() #生成随机数 def get_random_num(self): n = random.randint(4,12) rnum = "ABCDEFGHIJKLMNOPQRSTUVWXYZ23456789" st = string.join(random.sample(rnum, n)).replace(" ","") print st return st if __name__ == '__main__': S = Spider() print S.get('http://ip138.com/ip2city.asp') |
逻辑&&控制主脚本:google_list.py
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 | #! /usr/bin/env python #coding=utf-8 # 记录 pr,name,网址 import re import urllib from dbModel import MySQL from spiderModel import Spider HOST = 'http://www.google.com' PATH = '/Top/World/Chinese_Simplified/' R_DATA = re.compile(r'''<img src="/images/(?:pos.gif|cleardot.gif)"\s*width=(\d+.).*?</nobr></td>\s*<td><font face="arial,sans-serif"><a href="([^"]*?)">([^<]*?)</a>''') R_CHILD = r'''<a href="(?:%s)?([^/]*?)/">''' SQL = MySQL() S = Spider(HOST,'gb2312') #ISNO = True def save(keyword,pr='',url='',come_from='google_list'): SQL.insert_google_list(keyword,pr,url,come_from) print "keyword:%s,pr:%s,url:%s\n-----\n" % (keyword,pr,url) def get_child_list(html,path): r_list = re.compile( R_CHILD % path) child_list = r_list.findall(html) for child in child_list: keyword = urllib.unquote(str(child)) save(keyword) return child_list def get_data(html): data_list = R_DATA.findall(html) if data_list != []: # print data_list for data in data_list: pr,url,keyword = data if pr[-1] != ',': pr = 0 else: pr = pr[:-1] pr = str(int(pr)/4) save(keyword,pr,url) return def get_html(path=PATH): global ISNO url = HOST+path print "Get html,url: %s" % url html = S.get(url) if not html: return html = html.encode('utf-8') get_data(html) child_paths = get_child_list(html,path) for child in child_paths: # if ISNO and child != '%E8%B4%AD%E7%89%A9': # continue # ISNO = False child_path = path + child + '/' get_html(child_path) if __name__ == "__main__": get_html(PATH) |
存储model: DBmodel.py
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 | #! /usr/bin/env python #coding=utf-8 import MySQLdb class MySQL(object): def __init__(self,db_name='keywordict'): self.db_name = db_name self.cursor = self._connect() def _connect(self): conn = MySQLdb.connect(host='127.0.0.1', user='root',passwd='root',charset='utf8') conn.select_db(self.db_name) return conn.cursor() def insert(self,value): self.cursor.execute("insert into keyword_list values(%s)" % (value)) def insert_google_list(self,keyword,pr,url,come_from): self.cursor.execute('''insert into keyword_google(`keyword`,`pr`,`url`,`from`) values(%s,%s,%s,%s) ''',(keyword,pr,url,come_from)) def close(self): self.cursor.close(); if __name__ == "__main__": aa = MySQL() aa.insert_google_list('门事网.网络门事件','3','http://wwww.doorthing.com') |
相关文章
about 编码的一段话
=Python编码和Windows控制台= 我发现,很多初学者出错的地方都在print语句,这牵涉到控制台的输出。我不了解linux,所以只说控制台的。 首先,Windows的控制台确实是unicode(utf16_le编码)的,或者更准确的说使用字符为单位输出文本的。 但是,程序的执行是可以被重定向到文件的,而文件的单位是“字节”。 所以,对于C运行时的函数printf之类的,输出必须有一个编码,把文本转换成字节。可能是为了兼容95,98, 没有使用unicode的编码,而是mbcs(不是gbk之类的)。 windows的mbcs,也就是ansi,它会在不同语言的windows中使用不同的编码,在中文的windows中就是gb系列的编码。 这造成了同一个文本,在不同语言的windows中是不兼容的。 现在我们知道了,如果你要在windows的控制台中输出文本,它的编码一定要是“mbcs”。 对于python的unicode变量,使用print输出的话,会使用sys.getfilesystemencoding()返回的编码,把它变成str。 如果是一个utf8编码str变量,那么就需要 print s.decode('utf8').encode('mbcs') 最后,对于str变量,file文件读取的内容,urllib得到的网络上的内容,都是以“字节”形式的。 它们如果确实是一段“文本”,比如你想print出来看看。那么你必须知道它们的编码。然后decode成unicode。 如何知道它们的编码: 1.事先约定。(比如这个文本文件就是你自己用utf8编码保存的) 2.协议。(python文件第一行的#coding=utf8,html中的等) 3.猜。