使用正则表达式爬取豆瓣TOP250电影海报

359 阅读1分钟

阿甘正传.png

本篇使用正则表达式对豆瓣TOP250电影的海报进行了爬取。未使用b4soup
和etree,xpath。
主要问题是解决豆瓣反爬。用了3种方式解决反爬。
1.requests库的proxy参数可以使用IP代理的方式进行代理。
2.在headers中携带cookie。
3.在爬取图片时使用sleep。防止速度太快被认为是爬虫。
如何得到cookie? 登录豆瓣网页端。点击右上角个人主页。
之后使用开发者工具,点开网络。第一个东西的请求头里面有cookie。如图所示

图片.png 我的是firefox浏览器。别的浏览器也是一样的。
总体代码的思路就是先从top250上拿出每个图片的url。
再分别发get请求。代码有写。
以及在re.compile中re.DOTALL的使用。代表.可以匹配换行符。如果不这样的话。跨行的标签无法被提取。
代码

import requests
import re
import os
import time
import random
headers = {
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:104.0) Gecko/20100101 Firefox/104.0',
    'Cookie':'用你自己的'
}

# 不同的代理IP,代理ip的类型必须和请求url的协议头保持一致
proxy_list = ['122.9.101.6','47.113.90.161','122.152.196.126','114.215.174.227','119.185.30.75']

def get_html(url):
    '''Request a web page and get the source code'''
    try:
        html = requests.get(url, headers=headers,proxies={'http':random.choice(proxy_list)})
        return html.text
    except requests.exceptions.RequestException:
        print(url, '请求失败')

def download_image(html):
    # print(html)
    iter1=re.compile(r'<div class="pic">.*?<img.*?alt="(?P<movie_name>.*?)" src="(?P<img_url>.*?)".*?>.*?</div>',re.DOTALL)
    result1=iter1.finditer(html)
    movie_names=[]
    img_urls=[]
    for i in result1:
        movie_names.append(i.group('movie_name'))
        img_urls.append(i.group('img_url'))
    for name,url in zip(movie_names,img_urls):  # 拿到每张图片的下载地址
        time.sleep(1)  # 避免大规模访问   导致网站崩
        response = requests.get(url, headers=headers,proxies={'http':random.choice(proxy_list)})  # 这个是请求图片
        dir_name = './pics'
        if not os.path.exists(dir_name):
            os.mkdir(dir_name)
        with open(dir_name + "/" + name+'.png', "wb") as f:  # 加/是为了体现目录的替换
            f.write(response.content)

if __name__ == '__main__':
    urls = ['https://movie.douban.com/top250?start={}&filter='.format(i * 25) for i in range(0, 10)]
    for url in urls:
        html = get_html(url)
        download_image(html)