1 # -*- coding:utf-8 -*-
2
3 import urllib2
4 from lxml import etree
5 import json
6
7 class Spider_qiushi(object):
8 '''
9 糗事百科爬虫,可以根据用户输入的页码进行段子提供者、内容、喜欢的人数及评论数的爬取
10 '''
11
12 #初始化爬虫相关属性
13 def __init__(self,start_page,end_page):
14 self.start_page = start_page
15 self.end_page = end_page
16 #ie9的User-Agent(因为各个网站对于不同浏览器的响应内容可能会有差异,但ie浏览器是最为标准的,一般情况页面html源码用xpath响应的内容,在ie浏览器里是一致的)
17 self.headers = {'User-Agent':'Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0;'}
18 self.url = 'https://www.qiushibaike.com/8hr/page/'
19 self.filename = start_page - 1
23 #组合url,并组成fullurl列表
24 def full_url(self):
25 url_list = []
26 for num in range(self.start_page, self.end_page+1):
27 fullurl = self.url + str(num) +'/'
28 url_list.append(fullurl)
29
30 #print url_list #for test
31 return url_list
32
33 #对组合的url进行访问,构建请求,返回响应
34 def load_page(self,url_list):
36 for url in url_list:
37 request = urllib2.Request(url, headers = self.headers)
38 response = urllib2.urlopen(request)
39 #用read读取,返回的是字符串
40 html = response.read()
41 #用etree解析html为HTML DOM模型,并用xpath语法查找
42 html_dom = etree.HTML(html)
43 #段子html根节点列表
44 gen_list = html_dom.xpath('//div[contains(@id,"qiushi_tag_")]')
45
46 self.filename += 1
47 #每一页的内容组合一个json文件,取一个含有页数的名字
48 filename = str(self.filename) + '页段子合集.json'
49
50 #在循环内定义一个dict,每次循环都为空字典,目的是为下层循环存数据使用
51 info = {}
52
53 #打印提示
54 print '正在爬取第'+str(self.filename)+'页'
55
56 for gen in gen_list: #gen表示根节点。。。水平太次,起名不会啊。。。可以用selector来当变量
57
58 name = gen.xpath('.//h2')[0].text.strip() #这里是取到标签下的内容时,要用text提出来,测试发现前后有空格,用strip方法去除
59 #先将段子内容从列表中拿出来,(拿出来的是个对象吧)再用text方法进行读取标签下的内容
60 content = gen.xpath('.//div[@class="content"]/span')[0].xpath("string(.)").strip()
#这里span标签下有br标签换行,用xpath("string(.)"),可以将其下内容全部选取,否侧只能提出第一个br换行前的内容
64 #因为不是所有段子内容中都有图片,所以将其先默认为列表(再想办法) 65 img = gen.xpath('./div[@class="thumb"]//img/@src') 66 smile = gen.xpath('.//i[@class="number"]')[0].text.strip() 67 comment = gen.xpath('.//i[@class="number"]')[1].text.strip() 76 #每次都使用上层循环的空字典 77 info = { 78 'name':name, 79 'content':content, 80 'img':img, 81 'smile':smile, 82 'comment':comment 83 } 84 85 #print '写入第'+str(self.filename)+'页所有数据' 86 87 #因为filename里面有汉字 88 89 #使用json.dumps将python的字典数据,转为json文件中的对象(也就是字典)数据 90 with open(filename, "a") as f: 91 f.write(json.dumps(info, ensure_ascii = False).encode("utf-8")+'\n') 92 93 if __name__ == '__main__': 94 95 #用户输入要爬去的页面接口 96 start_page = int(raw_input('请输入起始页码:')) 97 end_page = int(raw_input('请输入结束页码:')) 98 99 #创建爬虫对象,传入页码参数100 myspider = Spider_qiushi(start_page, end_page)101 102 #利用用户传入的页码,组合url,为一个列表,用于各个页码的内容均爬取,变量url_list来接收103 url_list = myspider.full_url()104 105 #构建页面的请求……之后一系列操作,这里懒得思考了,先弄出来再说,就没再细分类方法,可以再简化一下代码106 myspider.load_page(url_list)107