# coding:utf-8 import urllib, urllib2, random, re ''' 1.确定要爬取得内容之后,先从url入手,分析每一页url的规律。 2.发送请求,获取网页源代码。 3.根据源代码html的规则,利用正则找出相关的标签,提取内容。 ''' # 1>设置爬取的url地址 base_url = "https://www.qiushibaike.com/hot/page/" # 2>设置请求头 user_agent_list = [ "Mozilla/5.0(Macintosh;IntelMacOSX10.6;rv:2.0.1)Gecko/ 20100101Firefox/4.0.1", "Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1)", "Opera/9.80(WindowsNT6.1;U;en)Presto/2.8.131Version/11.11", "Mozilla/5.0(Macintosh;IntelMacOSX10_7_0)AppleWebKit/535.11 (KHTML,likeGecko)Chrome/17.0.963.56Safari/535.11", "Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1)", "Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;Trident/4.0;SE2. XMetaSr1.0;SE2.XMetaSr1.0;.NETCLR2.0.50727;SE2.XMetaSr1.0)" ] # 3>设置随机IP值 ip_list = [ "183.32.89.224:6666", "27.40.156.43:61234", "110.166.254.120:808", "119.29.18.239:8888", "113.218.218.237:808" ] # 创建一个用于获取网页数据的函数 def down_load(page): # 拼接每一页页面的绝对路径 absolute_url = base_url + str(page) + '/' headers = { 'User-Agent': random.choice(user_agent_list) } request = urllib2.Request(absolute_url, headers=headers) # proxies = {'https':random.choice(ip_list)} # print(proxies) # proxy_handler = urllib2.ProxyHandler(proxies) # opener = urllib2.build_opener(proxy_handler) # # # 通过IP代理对象,发送http请求 # response = opener.open(request) response = urllib2.urlopen(request) # 获取网页源代码的内容 origin_code = response.read() # 提取糗事百科中的作者昵称,段子内容 # .*?<h2>: 采用非贪婪匹配模式,找到后面的<h2> # (.*?)</h2>: 采用非贪婪模式提取<h2></h2>中间的内容 # pattern = re.compile(r'<div class="author clearfix">.*?<h2> (.*?)</h2>.*?<div class="content">.*?<span>(.*?)</span>', re.S) # # info_list = re.findall(pattern, origin_code) # for author, content in info_list: # print '作者:', author.strip('\n') # print '内容:', content.strip('\n') # 提取段子的用户昵称,用户年龄,段子内容,好笑数,评论数 # pattern = re.compile(r'<div class="author clearfix">.*?<h2> (.*?)</h2>.*?<div class="articleGender.*?Icon">(.*?)</div>.*?<div class="content">.*?<span>(.*?)</span>.*?<div class="stats">.*? <i class="number">(.*?)</i>.*?<a.*?href="(.*?)".*?>.*?<i class= "number">(.*?)</i>', re.S) # all_info_list = re.findall(pattern, origin_code) # for nick_name, age, content, smail_num, href, cmt_num in all_info_list: # nick_name = nick_name.strip('\n') # age = age.strip('\n') # content = content.strip('\n') # smail_num = smail_num.strip('\n') # href = href.strip('\n') # cmt_num = cmt_num.strip('\n') # # best_cmt = best_cmt.strip('\n') # print '用户昵称:', nick_name # print '用户年龄:', age # print '内容:', content # print '好笑数:', smail_num # print '评论数:', cmt_num # print '最佳评论:', best_cmt # 在获取所有评论之前,先判断该条段子内容是否有评论,有的话再执行提取的逻辑。 # print '------评论区-------' # if int(cmt_num) != 0: # get_all_comments(href, headers) # else: # print '没有评论内容!' # 只获取没有图片的段子内容 pattern = re.compile(r'<div class="author clearfix">.*?<h2>(.*?) </h2>.*?<div class="content">.*?<span>(.*?)</span>.*?</div>(.*?) </div>.*?<div class="stats">.*?<i class="number">(.*?)</i>.*? <i class="number">(.*?)</i>', re.S) content_list = re.findall(pattern, origin_code) count = 0 for content_tuple in content_list: # 从元组中提取第三个分组信息,看信息中是否包含img标签 has_img = re.search(r"img", content_tuple[2]) if not has_img: # 获取没有图片的段子内容 print '用户昵称:', content_tuple[0].strip('\n') print '内容:', content_tuple[1].strip('\n') print '好笑数:', content_tuple[3].strip('\n') print '评论数:', content_tuple[4].strip('\n') count += 1 print '段子数量:',count def get_all_comments(href, headers): # 拼接详情页面的绝对路径 abs_url = "https://www.qiushibaike.com" + href request = urllib2.Request(abs_url, headers=headers) origin_code = urllib2.urlopen(request).read() # 根据正则表达式从源码中提取数据 pattern = re.compile(r'<a.*?class="userlogin".*?>(.*?)<div class=".*?Icon">(.*?)</div>.*?<span class="body">(.*?)</span>', re.S) all_comments_info_list = re.findall(pattern, origin_code) for name, age, content in all_comments_info_list: print '评论人:',name.strip('\n') print '评论人年龄:',age.strip('\n') print '评论内容:',content.strip('\n') # urllib2这个模块在爬取内容的时候,采用的是单线程,同步获取。不适合深度爬取。 # 多线程,异步爬取,非常适合深度爬取。 # 静态页面和动态页面 # 静态页面中的数据一般都是在第一次请求的时候,服务器就直接将这些数据放在响应体 中返回到客户端,客户端解析数据直接展示。平常通过查看网页源代码的方式看到的内容, 都属于静态页面的内容。一般的博客,段子,新闻等页面中的内容都属于静态页面。 # urllib2/requests/scrapy:获取的都是静态页面内容,无法获取动态页面内容。 # 动态页面:数据一般在第一次请求的时候,会先返回静态页面的内容,浏览器在加载完 静态页面之后,会再通过Ajax继续向服务器发送第二次/第三次请求,请求一些动态数据, 再进行展示。 # selenium+phantjs: 实现动态页面内容的抓取。 if __name__ == '__main__': for x in xrange(1, 2): down_load(x)
代理IP爬取糗事百科
最新推荐文章于 2020-10-19 21:53:52 发布