Python爬虫实战文档格式.docx
- 文档编号:21238231
- 上传时间:2023-01-28
- 格式:DOCX
- 页数:92
- 大小:7.05MB
Python爬虫实战文档格式.docx
《Python爬虫实战文档格式.docx》由会员分享,可在线阅读,更多相关《Python爬虫实战文档格式.docx(92页珍藏版)》请在冰豆网上搜索。
request=urllib2.Request(url)
response=urllib2.urlopen(request)
printresponse.read()
excepturllib2.URLError,e:
ifhasattr(e,"
code"
):
reason"
运行程序,哦不,它竟然报错了,真是时运不济,命途多舛啊
line373,in_read_status
raiseBadStatusLine(line)
lib.BadStatusLine:
'
'
好吧,应该是headers验证的问题,我们加上一个headers验证试试看吧,将代码修改如下
17
user_agent='
Mozilla/4.0(patible;
MSIE5.5;
WindowsNT)'
headers={'
User-Agent'
:
user_agent}
request=urllib2.Request(url,headers=headers)
嘿嘿,这次运行终于正常了,打印出了第一页的HTML代码,大家可以运行下代码试试看。
在这里运行结果太长就不贴了。
好,获取了HTML代码之后,我们开始分析怎样获取某一页的所有段子。
首先我们审查元素看一下,按浏览器的F12,截图如下
我们可以看到,每一个段子都是<
divclass=〞article
block
untaggedmb15″id=〞…〞>
…<
/div>
包裹的内容。
现在我们想获取发布人,发布日期,段子内容,以与点赞的个数。
不过另外注意的是,段子有些是带图片的,如果我们想在控制台显示图片是不现实的,所以我们直接把带有图片的段子给它剔除掉,只保存仅含文本的段子。
所以我们参加如下正如此表达式来匹配一下,用到的方法是re.findall是找寻所有匹配的内容。
方法的用法详情可以看前面说的正如此表达式的介绍。
好,我们的正如此表达式匹配语句书写如下,在原来的根底上追加如下代码
content=response.read().decode('
utf-8'
)
pattern=re.pile('
<
div.*?
class="
author.*?
>
.*?
a.*?
/a>
(.*?
)<
class'
+
="
content"
title="
)"
divclass="
stats.*?
number"
/i>
re.S)
items=re.findall(pattern,content)
foriteminitems:
printitem[0],item[1],item[2],item[3],item[4]
现在正如此表达式在这里稍作说明
1〕.*?
是一个固定的搭配,.和*代表可以匹配任意无限多个字符,加上?
表示使用非贪婪模式进展匹配,也就是我们会尽可能短地做匹配,以后我们还会大量用到.*?
的搭配。
2〕(.*?
)代表一个分组,在这个正如此表达式中我们匹配了五个分组,在后面的遍历item中,item[0]就代表第一个(.*?
)所指代的内容,item[1]就代表第二个(.*?
)所指代的内容,以此类推。
3〕re.S标志代表在匹配时为点任意匹配模式,点.也可以代表换行符。
现在我们可以看一下局部运行结果
儒雅男神2015-02-1714:
34:
42
小时候一个一个拆着放的举个爪…
divclass=〞thumb〞>
ahref=〞/article/100705418?
list=hot&
s=4747301″
target=〞_blank〞onclick=〞_hmt.push([‘_trackEvent’,‘post’,‘click’,‘signlePost’])〞>
imgsrc=〞pic.qiushibaike./system/pictures/10070/100705418/medium/app100705418.jpg〞alt=〞糗事#100705418″/>
7093奇怪的名字啊2015-02-1714:
49:
回家的路,你追我赶,回家的心情和窗外的阳光一样灿烂。
一路向前,离亲人越来越近了。
哪里有爸妈哪里才是家,希望所有糗友的爸爸妈妈都身体健康…….
4803
这是其中的两个段子,分别打印了发布人,发布时间,发布内容,附加图片以与点赞数。
其中,附加图片的内容我把图片代码整体抠了出来,这个对应item[3],所以我们只需要进一步判断item[3]里面是否含有img这个字样就可以进展过滤了。
好,我们再把上述代码中的for循环改为下面的样子
haveImg=re.search("
img"
item[3])
ifnothaveImg:
printitem[0],item[1],item[2],item[4]
现在,整体的代码如下
18
19
20
21
22
23
24
25
importre
运行一下看下效果
恩,带有图片的段子已经被剔除啦。
是不是很开森?
3.完善交互,设计面向对象模式
好啦,现在最核心的局部我们已经完成啦,剩下的就是修一下边边角角的东西,我们想达到的目的是:
按下回车,读取一个段子,显示出段子的发布人,发布日期,内容以与点赞个数。
另外我们需要设计面向对象模式,引入类和方法,将代码做一下优化和封装,最后,我们的代码如下所示
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
__author__='
CQC'
importthread
importtime
#糗事百科爬虫类
classQSBK:
#初始化方法,定义一些变量
def__init__(self):
self.pageIndex=1
self.user_agent='
#初始化headers
self.headers={'
self.user_agent}
#存放段子的变量,每一个元素是每一页的段子们
self.stories=[]
#存放程序是否继续运行的变量
self.enable=False
#传入某一页的索引获得页面代码
defgetPage(self,pageIndex):
+str(pageIndex)
#构建请求的request
request=urllib2.Request(url,headers=self.headers)
#利用urlopen获取页面代码
#将页面转化为UTF-8编码
pageCode=response.read().decode('
returnpageCode
returnNone
#传入某一页代码,返回本页不带图片的段子列表
defgetPageItems(self,pageIndex):
pageCode=self.getPage(pageIndex)
ifnotpageCode:
print"
页面加载失败...."
items=re.findall(pattern,pageCode)
#用来存储每页的段子们
pageStories=[]
#遍历正如此表达式匹配的信息
#是否含有图片
#如果不含有图片,把它参加list中
#item[0]是一个段子的发布者,item[1]是发布时间,item[2]是内容,item[4]是点赞数
pageStories.append([item[0].strip(),item[1].strip(),item[2].strip(),item[4].strip()])
returnpageStories
#加载并提取页面的内容,参加到列表中
defloadPage(self):
#如果当前未看的页数少于2页,如此加载新一页
ifself.enable==True:
iflen(self.stories)<
2:
#获取新一页
pageStories=self.getPageItems(self.pageIndex)
#将该页的段子存放到全局list中
ifpageStories:
self.stories.append(pageStories)
#获取完之后页码索引加一,表示下次读取下一页
self.pageIndex+=1
#调用该方法,每次敲回车打印输出一个段子
defgetOneStory(self,pageStories,page):
#遍历一页的段子
forstoryinpageStories:
#等待用户输入
input=raw_input()
#每当输入回车一次,判断一下是否要加载新页面
self.loadPage()
#如果输入Q如此程序完毕
ifinput=="
Q"
return
printu"
第%d页\t发布人:
%s\t发布时间:
%s\n%s\n赞:
%s\n"
%(page,story[0],story[1],story[2],story[3])
#开始方法
defstart(self):
正在读取糗事百科,按回车查看新段子,Q退出"
#使变量为True,程序可以正常运行
self.enable=True
#先加载一页内容
#局部变量,控制当前读到了第几页
nowPage=0
whileself.enable:
iflen(self.stories)>
0:
#从全局list中获取一页的段子
pageStories=self.stories[0]
#当前读到的页数加一
nowPage+=1
#将全局list中第一个元素删除,因为已经取出
delself.stories[0]
#输出该页的段子
self.getOneStory(pageStories,nowPage)
spider=QSBK()
spider.start()
好啦,大家来测试一下吧,点一下回车会输出一个段子,包括发布人,发布时间,段子内容以与点赞数,是不是感觉爽爆了!
我们第一个爬虫实战项目介绍到这里,欢迎大家继续关注,小伙伴们加油!
Python爬虫实战〔2〕:
XX贴吧帖子
大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取XX贴吧的帖子。
与上一篇不同的是,这次我们需要用到文件的相关操作。
首先,我们先观察一下XX贴吧的任意一个帖子。
比如:
tieba.baidu./p/3138733512?
see_lz=1&
pn=1,这是一个关于NBA50大的盘点,分析一下这个地址。
代表资源传输使用协议
tieba.baidu.是XX的二级域名,指向XX贴吧的服务器。
/p/3138733512是服务器某个资源,即这个帖子的地址定位符
see_lz和pn是该URL的两个参数,分别代表了只看楼主和帖子页码,等于1表示该条件为真
所以我们可以把URL分为两局部,一局部为根底局部,一局部为参数局部。
例如,上面的URL我们划分根底局部是
tieba.baidu./p/3138733512,参数局部是
?
pn=1
熟悉了URL的格式,那就让我们用urllib2库来试着抓取页面内容吧。
上一篇糗事百科我们最后改成了面向对象的编码方式,这次我们直接尝试一下,定义一个类名叫BDTB(XX贴吧),一个初始化方法,一个获取页面的方法。
其中,有些帖子我们想指定给程序是否要只看楼主,所以我们把只看楼主的参数初始化放在类的初始化上,即init方法。
另外,获取页面的方法我们需要知道一个参数就是帖子页码,所以这个参数的指定我们放在该方法中。
综上,我们初步构建出根底代码如下:
#XX贴吧爬虫类
classBDTB:
#初始化,传入基地址,是否只看楼主的参数
def__init__(self,baseUrl,seeLZ):
self.baseURL=baseUrl
self.seeLZ='
see_lz='
+str(seeLZ)
#传入页码,获取该页帖子的代码
defgetPage(self,pageNum):
url=self.baseURL+self.seeLZ+'
&
pn='
+str(pageNum)
returnresponse
baseURL='
tieba.baidu./p/3138733512'
bdtb=BDTB(baseURL,1)
bdtb.getPage
(1)
运行代码,我们可以看到屏幕上打印出了这个帖子第一页楼主发言的所有内容,形式为HTML代码。
1〕提取帖子标题
首先,让我们提取帖子的标题。
在浏览器中审查元素,或者按F12,查看页面源代码,我们找到标题所在的代码段,可以发现这个标题的HTML代码是
h1title="
纯原创我心中的NBA2014-2015赛季现役50大"
style="
width:
396px"
纯原创我心中的NBA2014-2015赛季现役5
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Python 爬虫 实战