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

it2022-05-05  140

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

猫眼电影

定义一个响应网页的函数 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下找到 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 #把得到的网页返回,以供后面解析网页使用 定义一个解析页面的函数

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

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

豆瓣电影

定义一个响应网页的函数 和上面一样 页面变化规律: 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递增定义一个获取网页的函数 和上面类似,把url=改一下 url='https://movie.douban.com/top250?start='+str(j) 定义一个解析页面的函数 这个正则可以算是绞尽脑汁了,别骂我菜 c=re.sub(' ','',html) pattern=re.compile('<div class="pic">.*?<em class="">(.*?)</em>.*?<img.*?src="(.*?)" class="">.*?div class="info.*?class="hd".*?class="title">(.*?)</span>.*?class="other">.*?</span>.*?<div class="bd">.*?<p class="">\s*(.*?)<br>.*?</p>.*?class="star.*?<span class=".*?"></span>.*?span class="rating_num".*?average">.*?</span>',re.S)

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

def parse_page(html): pattern=re.compile('<div class="pic">.*?<em class="">(.*?)</em>.*?<img.*?src="(.*?)" class="">.*?div class="info.*?class="hd".*?class="title">(.*?)</span>.*?class="other">.*?</span>.*?<div class="bd">.*?<p class="">\s*(.*?)<br>.*?</p>.*?class="star.*?<span class=".*?"></span>.*?span class="rating_num".*?average">.*?</span>',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() #这里的其他内容和上面一样,如果想保存图片,复制上面的保存图片代码 最后我们写一个主函数,调用它们 这里的递增应该为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="pic">.*?<em class="">(.*?)</em>.*?<img.*?src="(.*?)" class="">.*?div class="info.*?class="hd".*?class="title">(.*?)</span>.*?class="other">.*?</span>.*?<div class="bd">.*?<p class="">\s*(.*?)<br>.*?</p>.*?class="star.*?<span class=".*?"></span>.*?span class="rating_num".*?average">.*?</span>',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()

最新回复(0)