爬虫福利一 之 27报网MM

付费节点推荐


免费节点


节点使用教程


  1. import os
  2. import time
  3. import requests
  4. from lxml import etree
  5. class MeiZiSpider(object):
  6. """27 bao website MM spider"""
  7. def __init__(self):
  8. self.base_url = 'https://www.27bao.com/meinv/list_1.html'
  9. # self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"}
  10. self.headers = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'}
  11. # 构建url的前缀
  12. self.url_prefix = 'https://www.27bao.com'
  13. # 构建第二层url的前缀
  14. self.inner_url_prefix = 'https://www.27bao.com/meinv/'
  15. # 构建点开每个美女内部的所有url
  16. self.inner_url = 'https://www.27bao.com/meinv/56870_{}.html'
  17. # 文件保存的路径
  18. # linux路径
  19. # self.path = '/home/python/Desktop/27baomeimei/'
  20. # windows路径
  21. self.path = 'C:/Users/Nick/Desktop/27baomeimei/'
  22. def send_first_req(self):
  23. """发送第一层请求,返回首页响应的html内容"""
  24. html_str = requests.get(self.base_url, headers=self.headers).content.decode()
  25. return html_str
  26. def get_total_page(self):
  27. """获取网站美女图片总页数"""
  28. # 模拟发送请求, 返回响应数据(便于提取总页数)
  29. html_str = self.send_first_req()
  30. # 将返回的 html字符串 转换为 element对象
  31. element_obj = etree.HTML(html_str)
  32. # 提取末页的url, 再切片提取最大页数
  33. total_page = element_obj.xpath('//*[@id="pages"]/a[9]/@href')[0].split('_')[-1].split('.')[0]
  34. print('========该网站美女图片目前共有 {} 页========'.format(total_page))
  35. return total_page
  36. def get_each_girl_url(self, each_page_url):
  37. """第一层解析 ---> 获取每一页每个女孩的url"""
  38. # 用于存放拼接后每个女孩的url
  39. girl_url_list = []
  40. # 模拟发送请求, 返回响应数据(便于提取url)
  41. html_str = self.send_request(each_page_url)
  42. # 将返回的 html字符串 转换为 element对象
  43. element_obj = etree.HTML(html_str)
  44. # 提取所有url后缀 ---> 列表
  45. url_postfix = element_obj.xpath('/html/body/div[2]/div[2]/ul/li/a/@href')
  46. # 提取每个妹妹的标题, 便于后面命名
  47. url_title_li = element_obj.xpath('/html/body/div[2]/div[2]/ul/li/p/a/text()')
  48. # 遍历提取的url列表, 拼接完整的url, 并保存列表中
  49. for url in url_postfix:
  50. # 添加拼接后的url到列表
  51. girl_url_list.append(self.url_prefix + url)
  52. # print(girl_url_list)
  53. title_and_url_li = list(zip(url_title_li, girl_url_list))
  54. # print(title_and_url_li)
  55. return title_and_url_li
  56. def send_request(self, url):
  57. """发送第二层请求,返回响应的html内容"""
  58. # print(url)
  59. try:
  60. response = requests.get(url, headers=self.headers, timeout=5)
  61. except:
  62. return None
  63. # html_str = response.content.decode()
  64. html_str = response.content
  65. return html_str
  66. def parse_data(self, html_str):
  67. """第二层解析 ---> 获取当前女孩的每个url"""
  68. # 将返回的 html字符串 转换为 element对象
  69. element_obj = etree.HTML(html_str)
  70. each_image = element_obj.xpath('/html/body/div[3]/center/img/@src')[0]
  71. # print(each_image)
  72. return each_image
  73. def save_file(self, image_data, title, image_name):
  74. # 如果目录不存在, 就新建
  75. if not os.path.exists(self.path + title):
  76. os.makedirs(self.path + title)
  77. # 切换到新建目录下
  78. os.chdir(self.path + title)
  79. # for i in range(1, int(total_page) + 1):
  80. # image_name = str(i) + '.jpg'
  81. with open(image_name, 'wb') as f:
  82. f.write(image_data)
  83. def download(self):
  84. total_page = self.get_total_page()
  85. # 开循环, 爬取每个页面的每个妹妹的所有图片
  86. for page in range(1, int(total_page) + 1):
  87. print('\n正在爬取第 {} 页...\n'.format(page))
  88. # 构建每一页的url
  89. each_page_url = 'https://www.27bao.com/meinv/list_{}.html'.format(page)
  90. title_and_url_li = self.get_each_girl_url(each_page_url)
  91. # 遍历获取每个妹妹的总url
  92. for girl_url in title_and_url_li:
  93. # print(girl_url[1])
  94. # image_list = []
  95. html_str = self.send_request(girl_url[1])
  96. print('正在爬取的地址: {}'.format(girl_url[1]))
  97. # 获取目前爬取的美女内部总页数
  98. inner_total_page = etree.HTML(html_str).xpath('//*[@id="pages"]/a[last()-1]/text()')[0]
  99. print('\n目前爬取的美女图片共有 {} 张\n'.format(inner_total_page))
  100. # 循环并构造每一张图片的url, 请求, 解析, 并保存
  101. image_data = None
  102. for inner_page in range(1, int(inner_total_page) + 1):
  103. print('正在爬取 {} 第 {} 张图片...'.format(girl_url[0], inner_page))
  104. # 构造第二页以后的每个url
  105. each_image_url = girl_url[1].split('.html')[0] + '_{}.html'
  106. if inner_page == 1:
  107. # 获取第一页的url, 因为第一页和其他页的规律不一样,所以这里单独出来
  108. each_image_url = self.parse_data(html_str)
  109. # html_str = self.send_request(each_image_url)
  110. image_data = self.send_request(each_image_url)
  111. else:
  112. each_image_url = each_image_url.format(inner_page)
  113. # print(each_image_url)
  114. html_str = self.send_request(each_image_url)
  115. image = self.parse_data(html_str)
  116. image_data = self.send_request(image)
  117. # 如果请求图片的url在5秒之内无响应, 立即终止当前妹妹所有url的循环
  118. if image_data is None:
  119. print('当前MM的url无响应,正在跳转到下一个MM的url\n')
  120. break
  121. # 拼接保存图片的名称
  122. image_name = str(inner_page) + '.jpg'
  123. try:
  124. # 切换图片保存目录
  125. os.chdir(self.path + girl_url[0])
  126. # 判断文件是否存在, 存在则不再保存, 跳过
  127. if os.path.exists(image_name):
  128. print('第 {} 张已保存, 跳过...'.format(inner_page))
  129. continue
  130. except Exception as e:
  131. print('目录 {} 不存在, 正在新建...'.format(e))
  132. # 保存图片到本地
  133. self.save_file(image_data, girl_url[0], image_name)
  134. # image_list.append(image)
  135. # print(image_list)
  136. if image_data:
  137. print('\n{} 的所有图片已全部爬取完毕...\n'.format(girl_url[0]))
  138. # 休眠5秒中, 避免请求一直处于长连接导致ip被封
  139. time.sleep(10)
  140. if __name__ == '__main__':
  141. MeiZiSpider().download()

未经允许不得转载:Bcoder资源网 » 爬虫福利一 之 27报网MM

相关推荐

赞 (0)
分享到:更多 ()

评论 0

评论前必须登录!

登陆 注册