看到CSDN公众号推荐的一个猫眼电影前100的爬虫程序(来自于https://zhuanlan.zhihu.com/p/33819401),实现了下,记录一下过程:
主要分为3步:1. HTML下载器、2. HTML解析器、3. 数据存储器。
需要的库有requests,re(正则化表达式用),json(爬下来的数据格式是json格式,读取处理用),multiprocessing(多进程)。requests知识可以看这个点击打开链接,它是负责链接网站,处理http协议。
import requests
from requests.exceptions import RequestException
from multiprocessing import Pool
import re
import json
headers = {'User-Agent': 'Mozilla/5.0 '}
def get_one_page(url):
try:
res = requests.get(url, headers=headers)
if res.status_code == 200:
return res.text
return None
except RequestException:
return None
def parse_one_page(html):
pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
+'.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
+'.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',re.S)
items = re.findall(pattern,html)
for item in items:
yield{
'index': item[0],
'image': item[1],
'title': item[2],
'actor': item[3].strip()[3:],
'time': item[4].strip()[5:],
'score': item[5] + item[6]
} ##这里yield在每次循环都能返回值item,如果用return则只会在for循环完了返回最后一个的值
def write_to_file(content):
with open ('result.txt', 'a',encoding='utf-8') as f:
f.write(json.dumps(content,ensure_ascii=False) + '\n')
f.close()
def main(offset):
url = 'http://maoyan.com/board/4?offset=' + str(offset)
html = get_one_page(url)
for item in parse_one_page(html):
print(item)
write_to_file(item)
if __name__ == '__main__':
p = Pool()
p.map(main,[i*10 for i in range(10)])
注意事项:1.为什么write_to_file函数里面ensure_ascii=False?原因是json默认是以ASCII来解析code的,由于中文不在ASCII编码当中,因此就不让默认ASCII生效;open里面‘a’是指在txt文件中追加写,如果用‘w’则每次运行程序会覆盖掉原来的。
2. if __name__ == '__main__'这个代码的理解可以看这里,意思大概就是说如果是直接运行这个程序,冒号后面的代码会被运行,如果是import到别的程序里面,冒号后面的代码就不会被运行。(__name__ 是当前模块名,当模块被直接运行时模块名为 __main__ 。当模块被直接运行时,代码将被运行,当模块是被导入时,代码不被运行。)这里实现的是运行程序是实现多线程,加快爬虫速度。
服务器运行结果如下:
在控制台打印出来是正常的(因为程序在保存文件的时候已经设置为encoding='utf-8'),vim出来也是好的,但是直接双击打开txt显示是乱码,将txt文件下载在自己电脑后打开也显示正常,应该是服务器系统(ubantu(linux))的显示编码问题。