猫眼,豆瓣电影的requests和re爬虫

记录一下自己第一次的爬虫,爬豆瓣的正则表达式写的不好,如果以后再看的时候想办法改改

猫眼电影

  1. 定义一个响应网页的函数
def response_one_page(url):    #传入的参数是网址
	header={
		'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
	}        #提供UA,否则猫眼会无响应
	response=requests.get(url,headers=header)
	if response.status_code == 200:    #用状态码判断获取网页是否成功
		return response.text
	return None

上面的User-Agent可以在网页源码的Network下找到
猫眼,豆瓣电影的requests和re爬虫_第1张图片
Firefox,Chrome都可以找到User-Agent,然后复制粘贴
因为这次要获取的信息分了很多页面,但它们的变化是有规律的:
https://maoyan.com/board/4
https://maoyan.com/board/4?offset=10
https://maoyan.com/board/4?offset=20
给第一个页面加上?offset=0仍然是同一个页面: https://maoyan.com/board/4?offset=0
所以,我们可以找到规律,100个电影分了10个页面,每个页面的URL只有最后的offset在以10递增
2. 定义一个获取网页的函数

def get_one_page(j):   #参数为URL最后变化的数字
	url='https://maoyan.com/board/4?offset='+str(j)  #传入的参数为int型,所以要强制类型转换
	html=response_one_page(url)   #调用上面的响应函数,得到网页
	return html     #把得到的网页返回,以供后面解析网页使用
  1. 定义一个解析页面的函数

这个函数用正则来解析页面,提取我们想要的东西,是整个爬虫比较核心的东西

猫眼,豆瓣电影的requests和re爬虫_第2张图片

pattern=re.compile('
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?)

.*?releasetime.*?>(.*?)

.*?integer.*?>(.*?).*?fraction.*?>(.*?).*?
'
,re.S)
  • re的comile方法可以把正则字符串编译成正则表达式对象,方便复用
  • 观察网页源代码可知,每一个电影都是在dd标签里面,.*?(点,星,问号)表示任意字符,非贪婪
  • 在 i 标签里,我们可以得到排名,用括号括起来意味着我们一会儿可以提取它
  • data-src=""之间有我们需要的图片链接
  • 最后面的re.S帮我们匹配换行符
i=0
def parse_one_page(html):   #传入的参数是上面得到的网页
	pattern=re.compile('
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?)

.*?releasetime.*?>(.*?)

.*?integer.*?>(.*?).*?fraction.*?>(.*?).*?
'
,re.S) items=re.findall(pattern,html) #这里用的是正则解析页面 global i #传入参数,在下面保存图片时会用到 for item in items: dict={ 'index': item[0], 'image': item[1], 'title': item[2].strip(), 'actor': item[3].strip()[3:] if len(item[3])>3 else '', 'time': item[4].strip()[5:] if len(item[4])>5 else '', 'score': item[5].strip() + item[6].strip() } #这里是把得到的信息存成字典 r=requests.get(item[1]) #item[1]是每个电影图片的网页链接,通过get方法可以得到文本内容 path="D:/images/"+str(i)+".png" #为了存下图片并给图片命名,所以把路径提出来设置 f=open(path,"wb") f.write(r.content) #requests的content方法,可以得到二进制数据,用于抓取图片,视频,音频等 f.close() i+=1 f=open("D:/moves.txt","a+") f.write(str(dict)+'\n') #将所有信息写入文本文件,记住转成str型 f.close()
  1. 最后我们写一个主函数,调用它们
def main():
	for k in range(0,100,10):
		htmls=get_one_page(k)    #传入数字,用于改变URL的offset的值
		parse_one_page(htmls)
		time.sleep(3)        #响应过快会被猫眼反爬虫,所以要等待1,2秒
		print('*',end=' ')    #每完成一个页面,输出一颗星,就是为了好看

完整代码

import requests
import re
import time    #第三方库没有的可以在 windows的命令行里用 pip install requests下载

def response_one_page(url):
	header={
		'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
	}
	response=requests.get(url,headers=header)
	if response.status_code == 200:
		return response.text
	return None

def get_one_page(j):
	url='https://maoyan.com/board/4?offset='+str(j)
	html=response_one_page(url)
	return html

i=0
def parse_one_page(html):
	pattern=re.compile('
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?)

.*?releasetime.*?>(.*?)

.*?integer.*?>(.*?).*?fraction.*?>(.*?).*?
'
,re.S) items=re.findall(pattern,html) global i for item in items: dict={ 'index': item[0], 'image': item[1], 'title': item[2].strip(), 'actor': item[3].strip()[3:] if len(item[3])>3 else '', 'time': item[4].strip()[5:] if len(item[4])>5 else '', 'score': item[5].strip() + item[6].strip() } r=requests.get(item[1]) path="D:/images/"+str(i)+".png" f=open(path,"wb") f.write(r.content) f.close() i+=1 f=open("D:/moves.txt","a+") f.write(str(dict)+'\n') f.close() def main(): for k in range(0,100,10): htmls=get_one_page(k) parse_one_page(htmls) time.sleep(5) print('*',end=' ') main()

豆瓣电影

  1. 定义一个响应网页的函数
    和上面一样
    页面变化规律:
    https://movie.douban.com/top250
    https://movie.douban.com/top250?start=25
    https://movie.douban.com/top250?start=50
    给第一个页面加上?start=0仍然是同一个页面:https://movie.douban.com/top250?start=0
    所以,我们可以找到规律,250个电影分了10个页面,每个页面的URL只有最后的start在以25递增
  2. 定义一个获取网页的函数
    和上面类似,把url=改一下
url='https://movie.douban.com/top250?start='+str(j)
  1. 定义一个解析页面的函数
    这个正则可以算是绞尽脑汁了,别骂我菜
    猫眼,豆瓣电影的requests和re爬虫_第3张图片
c=re.sub(' ','',html)
	pattern=re.compile('
.*?(.*?).*?.*?div class="info.*?class="hd".*?class="title">(.*?).*?class="other">.*?.*?
.*?

\s*(.*?)
.*?

.*?class="star.*?.*?span class="rating_num".*?average">.*?',re.S)

在图片里可以看见,每个电影的信息保存在了li标签里,我想提取的是排名,图片url,电影名,导演演员名单,但在导演演员名中间有  ;还有大量空格,所以我在< br >前面加了\s*它可以表示空格。在查找之前用re.sub(’  ;’,’’,html)把  ;换成没有,这样方便正则表达式的书写

def parse_page(html):
	pattern=re.compile('
.*?(.*?).*?.*?div class="info.*?class="hd".*?class="title">(.*?).*?class="other">.*?.*?
.*?

\s*(.*?)
.*?

.*?class="star.*?.*?span class="rating_num".*?average">.*?',re.S) items=re.findall(pattern,c) for item in items: dict={ 'index': item[0], 'img': item[1], 'title': item[2], 'doctor': item[3] } f=open(file="D:/h.txt",mode="a+",encoding="utf-8") f.write(str(dict)+'\n') f.close() #这里的其他内容和上面一样,如果想保存图片,复制上面的保存图片代码
  1. 最后我们写一个主函数,调用它们
    这里的递增应该为25

完整代码

import requests
import re
import time

def response_one_page(url):
	header={
	'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
	}
	respone=requests.get(url,headers=header)
	if respone.status_code==200:
		return respone.text
	return None
def get_one_page(j):
	url='https://movie.douban.com/top250?start='+str(j)
	html=response_one_page(url)
	return html
def parse_page(html):
	c=re.sub(' ','',html)
	pattern=re.compile('
.*?(.*?).*?.*?div class="info.*?class="hd".*?class="title">(.*?).*?class="other">.*?.*?
.*?

\s*(.*?)
.*?

.*?class="star.*?.*?span class="rating_num".*?average">.*?',re.S) items=re.findall(pattern,c) for item in items: dict={ 'index': item[0], 'img': item[1], 'title': item[2], 'doctor': item[3] } f=open(file="D:/h.txt",mode="a+",encoding="utf-8") #指定存入文档的编码格式 f.write(str(dict)+'\n') f.close() def main(): for i in range(0,250,25): html=get_one_page(i) parse_page(html) print('*',end=' ') time.sleep(3) main()

你可能感兴趣的:(re,requests,Python)