OOP 发表于 2018-2-16 23:52

Yunen 发表于 2018-2-18 02:06

本帖最后由 Yunen 于 2018-2-18 19:39 编辑

代码不是很规范哦~
既然发出来了,就要考虑普及性
首先我们的python默认是没有requests和beautifulsoup库的,应在发布时充分考虑,可改urllib.request和正则表达式
要使用global 变量名 来调用全局变量
第二,headers 变量重复 可先创建一个基本headers字典 后在独自添加“host" : "www.xx.com" 和 referer
最后,使用失败,网站结构貌似发生了变化 beautifulsoup 失效

我重写了个爬虫,不用安装任何第三方库的,这个是爬整站的
这是单线程的,嫌慢的同学可以改写成多线程,利用queue+threading重写threading类的run方法,可以简单写个多线程
#!/usr/bin/env python3
# -*- encode: utf-8 -*-
import urllib.request
import re
import os
import time

#正则列表
img_url_partern = '<div class="content" id="content"><a ><img src="(.*?)" alt='
max_page_partern = '</i><a href="/mm/\w+/\w+">(.*?)</a><em'
img_name_partern = '<h2>(.*?)</h2>'
#为urllib.request.urlretrieve挂载referer头,绕过防盗链
opener=urllib.request.build_opener()
opener.addheaders=[("Referer","http://www.mmjpg.com/mm/1013/5")]
urllib.request.install_opener(opener)

def down_img(url_1):
    html_data = urllib.request.urlopen(url_1).read().decode()
    #取每组照片数
    max_page = re.compile(max_page_partern).findall(html_data)
    #读取每组照片名
    img_name = re.compile(img_name_partern).findall(html_data)
    print('当前采集的Url:' + url_1 + '共有' + max_page + '张照片')
    for c in range(1,int(max_page) + 1):
      url_2 = url_1 + '/' + str(c)
      #读取每张照片详情页
      html_data_2 = urllib.request.urlopen(url_2).read().decode()
      #提取照片地址
      img_url = re.compile(img_url_partern).findall(html_data_2)
      #检查目录
      if not os.path.exists("%s" % img_name):
            os.mkdir("%s" % img_name)
      save_name = "%s" % img_name + '\\' + str(c) + '.jpg'
      #初始化错误次数
      err_num = 0
      try:
            urllib.request.urlretrieve(img_url,filename=save_name)
      except:
            while err_num < 6:
                #休息1秒
                time.sleep(1)
                try:
                  urllib.request.urlretrieve(img_url,filename=save_name)
                  break
                except:
                  err_num += 1

def main():
    basic_url = r'http://www.mmjpg.com/mm/'
    #网站目前有最多1263组图片,for循环全部遍历
    for x in range(1,1264):
      url = basic_url + str(x)
      try:
            down_img(url)
      except:
            print('[-]The Url:' + url + ' Was No Found!')

if __name__ == '__main__':
    main()

teble 发表于 2018-3-4 22:35

Yunen 发表于 2018-2-18 02:06
代码不是很规范哦~
既然发出来了,就要考虑普及性
首先我们的python默认是没有requests和beautifulsoup ...

使用正则会出现无法使用正则匹配出网址,原因是<a >标签中漏了内容,所以借用你的代码改进了一下,同时开启了多线程进行爬图下载操作,本人初学python 如有不妥,请指正
import urllib.request
import re
import os
import time
import threading

img_url_partern = '<div class="content" id="content"><a href="+://[^\s]*"><img src="(.*?)" alt'
max_page_partern = '</i><a href="/mm/\w+/\w+">(.*?)</a><em'
img_name_partern = '<h2>(.*?)</h2>'
flag = 0
headers = {
    'Connection':'keep-alive',
    'Host':'http://www.mmjpg.com',
    'Referer':'http://www.mmjpg.com/mm/1017/4',
    'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36'
}


def getsize(file):
    size = os.path.getsize(file)
    size = size/float(1024)
    return round(size,0)


def down_img(url_1):
    html_data = urllib.request.urlopen(url_1).read().decode()
    max_page = re.compile(max_page_partern).findall(html_data)
    img_name = re.compile(img_name_partern).findall(html_data)
    print('当前采集的Url:' + url_1 + '共有' + max_page + '张照片')
    for c in range(1, int(max_page) + 1):
      url_2 = url_1 + '/' + str(c)
      html_data_2 = urllib.request.urlopen(url_2).read().decode()
      img_url = re.compile(img_url_partern).findall(html_data_2)
      if not os.path.exists("%s" % img_name):
            os.mkdir("%s" % img_name)
      save_name = "%s" % img_name + '\\' + str(c) + '.jpg'
      # print(img_url)
      for err_num in range(1,11):
            try:
                urllib.request.urlretrieve(url=img_url, filename=save_name)
            except:
                time.sleep(0.5)
                continue
            if getsize(save_name)<10:
                os.remove(save_name)
                continue
            else:
                break


def down_mul(basic_url):
    global flag
    while flag < 1264:
      flag += 1
      url = basic_url + str(flag)
      try:
            down_img(url)
      except:
            print('[-]The Url:' + url + ' Was No Found!')
      print('The No.'+str(flag)+' is OK')


def main():
    basic_url = 'http://www.mmjpg.com/mm/'
    for i in range(1,21):
      t = threading.Thread(target = down_mul,args = (basic_url,))
      t.start()
      print('['+str(i)+']Runing Star')


if __name__ == '__main__':
    opener = urllib.request.build_opener()
    header_list = []
    for key, value in headers.items():
      header_list.append((key, value))
    opener.addheaders = header_list
    urllib.request.install_opener(opener)
    main()

不老松 发表于 2018-2-17 00:11

感觉很不错,但是因为是小白,看不懂哦,还是谢谢分享!!!

简短的J 发表于 2018-2-17 00:19

哈哈 很好很喜欢!我之前在论坛下了个男人装破解版也挺好用的

nishuona 发表于 2018-2-17 01:52

看上去挺厉害的,但是不怎么看这东西

孤狼微博 发表于 2018-2-17 01:55

谢谢分享做个记号电脑查看

丶cold 发表于 2018-2-17 02:52

{:301_1005:} 厉害不会

ftmovie 发表于 2018-2-17 08:25

谢谢分享

Sukkk 发表于 2018-2-17 08:45

谢谢,授人以鱼不如授人以渔。谢谢你的方法

双眼皮的微笑 发表于 2018-2-17 08:59

看来我要学习这个语言了。

葫芦炒鸡蛋 发表于 2018-2-17 09:13

Python爬虫其实很简单的,关键看网站的反爬措施怎么样了。
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 用Python爬虫爬取美女写真