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