先上代码,此处代码参照 崔庆才博客-Python爬虫实战一之爬取糗事百科段子,感谢分享,在这里仅记录一下自己实战时的理解,如有不对之处,还请帮忙指正。
# -*- coding:utf-8 -*-
import urllib
import urllib2
import re
url = 'http://www.qiushibaike.com/hot/'
user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36'
headers = { 'User-Agent' : user_agent }
try:
request = urllib2.Request(url,headers = headers)
response = urllib2.urlopen(request)
content = response.read().decode('utf-8')
pattern = re.compile('<div.*?class="author.*?>.*?<a.*?</a>.*?<a.*?title="(.*?)".*?</a>.*?<div.*?class="content">(.*?)</div>(.*?)<div class="stats.*?class="number">(.*?)</i>',re.S)
items = re.findall(pattern,content)
for item in items:
haveImg = re.search("img",item[2])
if not haveImg:
print item[0],item[1],item[3]
print response.read()
except urllib2.URLError, e:
if hasattr(e,"code"):
print e.code
if hasattr(e,"reason"):
print e.reason
代码就不用多说了,重点解释一下正则表达式,
1).*? 是一个固定的搭配,.和*代表可以匹配任意无限多个字符,加上?表示使用非贪婪模式进行匹配,也就是我们会尽可能短地做匹配,以后我们还会大量用到 .*? 的搭配。
2)(.*?)代表一个分组,在这个正则表达式中我们匹配了五个分组,在后面的遍历item中,item[0]就代表第一个(.*?)所指代的内容,item[1]就代表第二个(.*?)所指代的内容,以此类推。
打开糗百,F12查看,发现每个片段对应的代码如下:
接下来,详细介绍一下,正则表达式中那一段字符串的意思。
<div.*?class="author.*?> : 匹配<div class="author clearfix">
.*?<a.*?</a> : 匹配接下来的第一行<a 至 </a>
.*?<a.*?title="(.*?)".*?</a> : 匹配第二行的<a 至 </a> 其中(.*?)匹配title后的内容
.*?<div.*?class="content">(.*?)</div> :(.*?)匹配 <div class="content">至</div>的内容,为段子的内容
(.*?) : 这个匹配<div class="thumb">至</div> 这段是段子中图片的URL,模糊匹配,这段程序不抓取图片的内容
(.*?)</i> : 匹配接下来投票数的内容