记录一下自己第一次的爬虫,爬豆瓣的正则表达式写的不好,如果以后再看的时候想办法改改
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('.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star.*?>(.*?).*?releasetime.*?>(.*?).*?integer.*?>(.*?).*?fraction.*?>(.*?).*? ',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()
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()
url='https://movie.douban.com/top250?start='+str(j)
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() #这里的其他内容和上面一样,如果想保存图片,复制上面的保存图片代码
- 最后我们写一个主函数,调用它们
这里的递增应该为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()