关于爬虫的文章,有时间要细细看一下面

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

谷歌网页目录数据抓取

Qign / 四月 12th, 2010 / 1 Comment / Tags: pythonspider抓取谷歌网页目录/ Posted in Work /

目标地址为: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之类的,输出必须有一个编码,把文本转换成字节。可能是为了兼容9598,
没有使用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.猜。

原文地址:https://www.cnblogs.com/lexus/p/1853140.html