Use-python-scrapy-lieqishi

在刷V2ex的时候,看到好多帖子在爬煎蛋妹子图,有帖子中有人回复说来试试lieqishi.com网站,然后我就钻研了一下。

本人以前从没学过python语言。所以改起来没有那么快。现在给大家共享下。

环境:Python 3.6.2

工具:EverEdit(编写代码的)、Fiddler(抓取网页请求)、Chrome(浏览器)

目标网站:https://lieqishi.com/index.php/fuli

分析

  • 浏览网站的时候,网址格式都为https://lieqishi.com/index.php/fuli/show/id/{文章编号},文章编号为1~3363(手工试出来的),后期网站增加这个值还会变大。
  • 很多图片需要登录后才能查看,不登录只能看到一张图片。
  • 登录后有些文章有翻页。
  • 有些文章需要消费金币才能查看,这个我就没办法了。(但是猜测有bug,消费一次后,再次查看还需要消费)

使用Fiddler进一步分析

  • 登录的时候是这个url,https://lieqishi.com/index.php/api/ulog/login?username=UserName&userpass=123456,使用GET方法,没有POST数据。
  • 登录之后需要查看的图片是这个网址返回html的,https://lieqishi.com/index.php/fuli/show/pay/{文章编号},返回的是url加密的数据,需要解密。
  • 可以使用Cookies的方式保持登陆。
  • 利用Chrome的F12查看网页代码,show页面中用#content 下的img标签来定位位置,取得图片的实际href。
  • pay页面中解密之后,直接用img标签来定位位置,取得图片的实际href。
  • 对于翻页的,取得当前页面下一页按钮(class=‘layui-laypage-next’)中的href是否与本页一致,不一致则表示有下一页。第二页的链接为https://lieqishi.com/index.php/fuli/show/pay/{文章编号}/2

实现功能点

  • 实现模拟登录,获取相应的cookies。用于后面的请求。
  • 循环获取所有文章对应的show和pay页面中的img标签的href,做成数组。
  • 用文章编号创建文件夹,把此文章下面的show和pay的img全部下载下来。
  • 随机获取user-agent,模拟不同浏览器浏览。
  • 文件存在则提示下载过,不再下载。

遇到的问题

  • ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
    • 此问题是由于Fiddler开着,会转发,关掉即可。
  • Max retries exceeded with url
    • 对于打开url获取img增加三次重试功能。
    • 对于下载图片的时候,出现报错等待几秒。
    • 设置requests.get的timeout。
  • 通过浏览器看到的url可能不是你实际要采集的url,一定要用Fiddler分析下。

代码

GitHub地址:https://github.com/laycher/reptile-lieqishi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# -*- coding: UTF-8 -*-
import requests
from urllib import request
from urllib import parse
from bs4 import BeautifulSoup
import urllib.parse
import os
import random
import time
 
download_path='D:/Media/Pictures/MMPic/'#你的图片保存路径
urls=['https://lieqishi.com/index.php/fuli/show/id/{}'.format(str(i))for i in range(1,3364,1)] #目前共3363张, [1,100) 。46、53
login_url='https://lieqishi.com/index.php/api/ulog/login?username=UserName&userpass=123456'
 
#Ctrl+Shift+J , document.cookie ,查看cookie
user_agent_list = [\
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"\
        "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",\
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",\
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",\
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",\
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",\
        "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",\
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",\
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",\
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",\
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",\
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",\
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",\
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",\
        "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",\
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",\
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",\
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",\
        'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.1 (KHTML, like Gecko) Maxthon/3.0.8.2 Safari/533.1'
       ]
#这里是user-agent和cookie,代码展示的只是样式,并非真实的user-agent和cookie,你要换成你自己的
 
requests.adapters.DEFAULT_RETRIES = 5
 
#url,网页地址; cookies,登录后获取的cookies;num_retries,重试次数,默认为3次
def openurl(url, cookies='', num_retries=3):
    try:
        html = requests.get(url,cookies=cookies)
    except requests.RequestException as e:
        print('Open error:', e)
        html = None
        if num_retries > 0:
            if hasattr(e, 'code') and 500 <= e.code < 600:
                # recursively retry 5xx HTTP errors
                print('Try again')
                return openurl(url, cookies,num_retries-1)
    return html
 
#url,网页地址; cookies,登录后获取的cookies; index,实际网页编号,否则分页的目录就错了
def get_info(url, cookies, index):
    print('Downloading:', url)
    wb_data=openurl(url,cookies,3)#发起网页请求
    if 'pay' in url :
        html=urllib.parse.unquote(wb_data.text.split("\'")[1])
        soup=BeautifulSoup(html,'html.parser')
        img=soup.select('img')#定位元素
    else :
        soup=BeautifulSoup(wb_data.text,'html.parser')#解析网页
        img=soup.select('#content > img')#定位元素
 
    next_page_url=url
    for i in soup.find_all('a',attrs={'class':'layui-laypage-next'}):
        next_page_url=i.get('href')
 
    #print(img)
    imgs_url=[]					#清空imgs数组
    for i in img:               #判断是否为GIF,是就pass,不是就添加到下载列表
        z=i.get('src')
        if str('gif') in str(z):
           pass
        else:
            imgs_url.append(z)
 
    print()
 
    #print(imgs_url)      #输出下载列表
    dir_name=download_path+index
    if not os.path.exists(dir_name) and imgs_url:
        os.makedirs(dir_name)
    download(imgs_url,dir_name)  #下载图片组
 
    if 'pay' not in url :
        get_info(url.replace('id','pay'),cookies,index)
 
    if next_page_url!=url :
        get_info(next_page_url,cookies,index)
 
#下载图片组
def download(imgs_url,dir_name):   
    for i in imgs_url:            #下载模块
        try:
        	r=requests.get(i,headers=get_headers())
        except:
	        print("Let me sleep for 5 seconds.ZZZzzz......")  
        	time.sleep(10)
        	r=requests.get(i,headers=get_headers(),timeout=30)
 
        file_name=dir_name+'/'+i.split('/')[-1]
        if not os.path.isfile(file_name) :	#文件不存在才会下载文件
            with open(file_name,'wb')as pic:
                pic.write(r.content)
 
            print(i)
        else:
            print(file_name+' : 此文件已存在,不再下载。')
 
    print()                  
 
#模拟登录,获取cookies
def login(url):
    login_Wdata=requests.get(url)
    return login_Wdata.cookies
 
#取header,随机agent
def get_headers():
	ua = random.choice(user_agent_list)
	headers={'User-Agent': random.choice(user_agent_list),'Connection': 'close'}
	return headers
 
#程序开始
def start():           
    cookies=login(login_url)
    for i in urls:
        index=i.split('/')[-1]
        get_info(i,cookies,index)
 
 
start()

 

To-Do-List

  • 为防止被反爬虫
    • 可以多申请几个账号,每次随机登陆某个账号。
    • 使用代理的方式去登陆,浏览网页或下载图片。代理地址可以爬取http://www.xicidaili.com/。
  • 文章编号范围可以设的很大,然后连续五个页面没有返回的话,就停止爬取。
  • .......
  • 但是我不想搞了。:)

此代码仅供参考,有违反什么的话,请告知。

>> 若为原创,转载请注明: 转载自Laycher's Blog

>> 本文链接地址: 利用Python爬取lieqishi网站图片

>> 订阅本站: http://feed.feedsky.com/laycher



无觅相关文章插件,快速提升流量