我发现自己没有整理和总结的习惯,有时是学了之后觉得会了,懒得整理,有时是没有时间,偶尔有时候想起来会写一篇。但是后来发现忘的还是挺快的,而且想找以前的东西的时候总是不太方便。不过人生在世,总要给这个世界留下点什么。把自己在学习中得到的东西,所思所想都记录下来,所以在此立个flag【狗头】,养成总结和写作的习惯=-=。
最近在看崔庆才老师的python3网络爬虫开发实战爬取猫眼top100的电影信息。总的来说,爬取的步骤分为两步,1)使用requests模块的get方法请求网页信息;2)使用正则表达式将信息匹配出来。步骤不麻烦,但是由于时间原因,http协议改为了https协议,不过也可能当时用的就是https协议,不过http请求会跳转为https请求,不过这个影响不大。另一个是如果像文中那样设置headers字段的话会被猫眼的服务器识别为爬虫,得到的是一个美团验证中心的页面。
1)请求页面
文中的headers只设置了一个User-Agent字段,但是会被识别为爬虫,所以最好将该请求的所有header字段都设置,这样猫眼也就无法识别爬虫和浏览器了。cookie字段不用设置,因为第一次请求是没有cookie的。
2)正则提取
正则提取最重要的就是正则表达式。
<dd>.*?<a href="(.*?)" title="(.*?)".*?<p class="star">(.*?)</p>.*?<p class="releasetime">(.*?)</p>.*?</dd>
这是我一开始写的正则式,还是很稚嫩,感觉太具体了,多了很多不必要的信息,我提取的信息和文中提取的信息不同,只提取了href 、电影名、主演、上映时间。
<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>
这是文中的一个正则表达式,我从中理解的正则表达式的书写原则是先找要匹配信息前面最近的锚点,然后再从锚点匹配到所要的信息。
<dd>.*?href="(.*?)" title="(.*?)".*?star.*?>(.*?)<.*?releasetim.*?>(.*?)<.*?</dd>
这是根据文中的方法书写的正则表达式
代码部分
import requests, re
main_url = 'https://maoyan.com/board/4'
films=[]
def getOnePage(url):
headers = {'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36",
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate, br',
'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Cache-Control': 'no-cache',
'Host':'maoyan.com',
'Pragma':'no-cache',
'Connection':'keep-alive',
'Upgrade-Insecure-Requests':'1'
}
respond = requests.get(url, headers=headers)
pattern ='<dd>.*?href="(.*?)" title="(.*?)".*?star.*?>(.*?)<.*?releasetim.*?>(.*?)<.*?</dd>'
result = re.findall(pattern, respond.text, re.S)
print(result)
films.extend(result)
def main():
all_url=[]
all_url.append(main_url)
for i in range(10,100,10):
tmp = main_url+'/?offset='+str(i)
all_url.append(tmp)
for u in all_url:
getOnePage(u)
# print(films[20])
with open('maoyan.txt','w') as f:
line =''
for i in range(100):
# print(films[i])
line_list= list(films[i])
line_list[2] = line_list[2].strip()
line = ' '.join(line_list)+'\n'
f.write(line)
main()