爬取猫眼top100电影

一、前言

其实爬取页面的思路都差不多,观察爬取页面源码,获取页面内容,根据源码的格式规律将自己需要的内容提取出来,提取后美化输出或者保存!
之前写过了如何爬取淘宝和京东的评论,其实这个可以不写的!!但是又遇到坑了所以还是写下来,记录一下错误!!

二、代码与问题

先上代码再说一下自己遇到的问题!

# -*- coding:utf-8 -*-
import requests
from requests.exceptions import RequestException
import re
import json
import time
from multiprocessing import Pool

"""
url= 'https://maoyan.com/board/4'
repsponse = requests.get(url)
print(repsponse.headers['content-type'])
print(repsponse.encoding)#response内容的编码
print(repsponse.apparent_encoding)#response headers里设置的编码
print(requests.utils.get_encodings_from_content(repsponse.text))#response返回的html header标签里设置的编码


"""
def get_url(url):
    try:
        #说明headers信息,不然一下就403错误了!
        heards = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
        #获取页面信息
        response = requests.get(url,headers=heards)
        #页面返回的status_code码为200则是爬取成功
        if response.status_code == 200:
            #声明页面返回内容的编码格式,不然一般是ISO-8859-1,就乱码了
            response.encoding = 'utf-8'
            return response.text
        return print("爬取失败")
    except RequestException:
        return print("爬取失败")

def parge_html(html):
    #编写正则表达式的格式
    #compile() 函数将一个字符串编译为字节代码
    pattern = re.compile('
.*?board-index.*?(\d+).*?name.*?(.*?).*?star">(.*?)

.*?releasetime">' +'(.*?)

.*?integer">(.*?).*?fraction">(\d+).*?
',re.S) #利用正则表达式获取需要的内容 items = re.findall(pattern,html) #print(items) #将内容转化为一个字典使其更容易观看 for item in items: yield{ 'index':item[0], 'name':item[1], 'star':item[2].strip()[3:], #strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。 'time':item[3][5:], 'score':item[4]+item[5] } def write_to_file(content): with open('result1.txt', 'a', encoding='utf-8') as f: #ensure_ascii=False,说明输出的内容不要用ASCII编码,这样结果才是中文 f.write(json.dumps(content,ensure_ascii=False) + '\n') #利用json.dumps将字典转为字符串 f.close() def main(offset): #切换页面观察URL的变化 url = 'https://maoyan.com/board/4?offset=' + str(offset) html = get_url(url) for item in parge_html(html): print(item) write_to_file(item) #print(html) if __name__ == "__main__": #单线程爬取 """ for i in range(10): time.sleep(10) main(i*10) """ #多线程 pool = Pool(processes = 10) #默认的话进程数为cpu_count()的值 pool.map(main,[i*10 for i in range(10)])
问题1:

我最开始写的是爬取一页的电影内容,没有用正则表达式转化提取,但是输出的内容是乱码的!
既然乱码就是编码问题了,由于我是已经声明utf-8的编码模式了,我以为是软件问题,我是用pycharm(第一次用我也不知道它初始编码是什么,之前一直用Spyder),我查了一下怎么修改pycharm的编码,file—>settings—>Editor—>File Encoding,一看那里有一个是gbk,我就都改为了utf-8!

image.png

但是重新输出后还是乱码!!
在网上找了好久,终于看到有一篇说到点了,其他大部分要么教我修改pycharm编码要么在程序一开始声明utf-8但是都没用!
原来是因为在你调用Response.text时对响应进行解码,如果http头部有声明则基本上按声明进行解码,没用它就会猜!使用默认的 ISO-8859-1解码,有时http头部声明了也还是按照这个解码!

print(repsponse.encoding)#response内容的编码
print(repsponse.apparent_encoding)#response headers里设置的编码
print(requests.utils.get_encodings_from_content(repsponse.text))#response返回的html header标签里设置的编码

可以输入上面的代码看一下是不是编码出问题,我的输出是:ISO-8859-1,utf-8,utf-8请求返回的内容变成了ISO-8859-1肯定乱码!
可以在获取内容后先输入:

response.encoding = 'utf-8'

声明请求返回内容是utf-8编码。

问题2:

问题1解决后我又爬了一次!这次没有乱码,但是因为我在调整编码的时候一直测试一直爬,猫眼觉得我的请求很可疑!禁止了我的请求,出现了403错误!
这个通过增加一个头部信息就好了,之前淘宝比较严格,头部信息比较多。这次就加了一个请求的浏览器类型就可以了!

问题3:

问题2解决后,我接着完善,刚刚是爬取一页,现在是十页!但是又出问题了爬的太频繁太快被要求验证身份了,也就是类似拼图,但是我爬取的内容还没完呢!少了一页,所以我又加了睡眠信息,每十秒爬一次,终于成功了!这是单线程!

接下来是多线程爬取:多线程一般默认是cpu_count()数,我的是8,但是我自己定义开了十个进程。
天下武功唯快不破!!!用了十个进程秒爬,估计猫眼没反应过来,最后爬取内容缺了一个而已!
但是多线程有一个缺点,就是爬取的内容不是按顺序的,本来是top100的电影从1-100,多线程的话内容有点乱!但是问题不大,因为它很快就好了。

参考:https://www.bilibili.com/video/BV1Si4y1s7S4?p=14
https://www.runoob.com/python/python-func-compile.html
https://www.runoob.com/python/att-string-strip.html
https://www.cnblogs.com/biangbiang/archive/2013/02/19/2916780.html
https://blog.csdn.net/a491057947/article/details/47292923
https://blog.csdn.net/weixin_43877278/article/details/103880644

你可能感兴趣的:(爬取猫眼top100电影)