专业的编程技术博客社区

网站首页 > 博客文章 正文

Python学习之爬取网页信息(python爬取网页数据步骤)

baijin 2024-10-24 08:44:54 博客文章 6 ℃ 0 评论

运行环境

Python 2.7 Windows 系统

其实用python爬取网页很简单,只有简单的几句话

import urllib2

page=urllib2.urlopen('url').read()

print page

输出page 你就会看到网页上面的所有内容

这样就可以获得到页面的内容。接下来再用正则匹配去匹配所需要的内容就行了。

但是,真正要做起来,就会有各种各样的细节问题。

登录

这是一个需要登录认证的网站。也不太难,只要导入cookielib和urllib库就行。

123import urllib,urllib2,cookielibcookiejar = cookielib.CookieJar()urlOpener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
这样就装载进一个cookie,用urlOpener去open登录以后就可以记住信息。

断线重连

如果只是做到上面的程度,不对open进行包装的话,只要网络状况有些起伏,就直接抛出异常,退出整个程序,是个很不好的程序。这个时候,只要对异常进行处理,多试几次就行了:

1
2
3
4
5
6
7
8
9
10
def multi_open(opener,*arg):
while True:
retryTimes=20
while retryTimes>0:
try:
return opener.open(*arg)
except:
print '.',
retryTimes-=1

正则匹配

  • 非贪婪匹配。比如这样一个标签:<span class='a'>hello</span>,要取出a来,如果写成这样的表达式,就不行了:<span class=.*>hello</span>。因为*进行了贪婪匹配。这是要用.?:<span class=.?>hello</span>。

  • 跨行匹配。实现跨行有一种思路是运用DOTALL标志位,这样.就会匹配到换行。但是这样一来,整个匹配过程就会变得很慢。本来的匹配是以行为单位的。整个过程最多就是O(nc2),n是行数,c是平均列数。现在极有可能变为O((nc)2)。我的实现方案是运用\n来匹配换行,这样可以明确指出匹配最多跨跃多少行。比如:abc\s*\n\s*def,就指出查找的是隔一行的。(.\n)?就可以指定是匹配尽可能少的行。

  • 这里其实还要注意一个点。有的行末是带有\r的。也就是说一行是以\r\n结尾的。当初不知道这一点,正则就调试了很久。现在直接用\s,表示行末空格和\r。

  • 无捕获分组。为了不对捕获的分组造成影响,上面的(.\n)可以改为(?:.\n),这样捕获分组时,就会忽略它。

  • 单括号要进行转义。因为单括号在正则里是用来表示分组的,所以为了匹配单括号就进行转义。正则字符串最好用的是带有r前缀的字符串,如果不是的话,则要对\再进行转义。

  • 快速正则。写了那么多模式,也总结出一规律出来。先把要匹配的字符相关的段落拿出来。要匹配的东西用(.?)代替。把换行\n替换为字符串\s\n\s*,再去掉行首行末的空格。整个过程在vim中可以很快就写好。

Excel操作

搜索Excel,可以得出几个方案来,一个是用xlrt/xlwt库,这个不管电脑上是否安装了Excel,都可以运行,但只能是xls格式的。还有一个是直接包装了com,需要电脑上安装了软件才行。


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
#coding:utf-8#
import xlwt
class XLS:
'''a class wrap the xlwt'''
MAX_ROW=65536
MAX_SHEET_NUM=3
def __init__(self,name,captionList,typeList,encoding='utf8',flushBound=1000):
self.name=name
self.captionList=captionList[:]
self.typeList=typeList[:]
self.workbookIndex=1
self.encoding=encoding
self.wb=xlwt.Workbook(encoding=self.encoding)
self.sheetIndex=1
self.__addSheet()
self.flushBound=flushBound
def __addSheet(self):
if self.sheetIndex != 1:
self.wb.save(self.name+str(self.workbookIndex)+'.xls')
if self.sheetIndex>XLS.MAX_SHEET_NUM:
self.workbookIndex+=1
self.wb=xlwt.Workbook(encoding=self.encoding)
self.sheetIndex=1
self.sheet=self.wb.add_sheet(self.name.encode(self.encoding)+str(self.sheetIndex))
for i in range(len(self.captionList)):
self.sheet.write(0,i,self.captionList[i])
self.row=1
def write(self,data):
if self.row>=XLS.MAX_ROW:
self.sheetIndex += 1
self.__addSheet()
for i in range(len(data)):
if self.typeList[i]=="num":
try:
self.sheet.write(self.row,i,float(data[i]))
except ValueError:
pass
else:
self.sheet.write(self.row,i,data[i])
if self.row % self.flushBound == 0:
self.sheet.flush_row_data()
self.row+=1
def save(self):
self.wb.save(self.name+str(self.workbookIndex)+'.xls')

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表