爬取TOP100榜猫眼电影信息 爬虫实战

写在前面

最近在学爬虫,跟着崔庆才大佬的个人网站学习。
今天跟着做了一个爬虫来爬取猫眼电影top100榜的电影信息。其中遇到了一些问题,这里就写成博客记录下来。

遇到的问题

  • 反爬虫机制:在进行html文档获取时,收到了403的状态码,这大概率代表是由于猫眼网站的反爬虫机制。这里的解决办法是在headers中加上user-agent信息。
  • 美团验证:在修改了headers之后,发现遇上了新的问题。收到的页面保存本地之后打开,发现是一个美团验证页面。通过这个页面,便可以正常访问,但我目前实力还做不到,所以寻找其他办法。最后发现,我之前修改头信息,user-agent中用的是火狐浏览器,而我之后尝试把修改成chrome之后便不会出现验证页面。
  • 源码在不同浏览器上显示不同:在写正则表达式时,在获取图片链接那一步总是发现不对,返回的结果是只有5个url,且url不对。然后我看了崔大佬写的正则表达式,他用的是data-src,但是我在源码上找了半天,却看不到这个data-src,最后终于发现,是浏览器的问题。我一开始用的是edge来查看源码,其中是没有data-src的,只有src,在换了火狐和chrome之后,便发现,原来真的是data-src。我也不知道为什么同样一样个网页在不同的浏览器上源码不一样,支持的html版本不一样?还是什么,无所谓了,我不是很关心原因是什么,但是这个坑我先mark了。
    FirefoxFirefox
    爬取TOP100榜猫眼电影信息 爬虫实战_第1张图片
    edge
    发现了这个问题之后,我才明白,怪不得本来应该匹配十个,最后只匹配到5个,且图片是错的原因:因为每个dd里,第二个img其实是data-src,而我写的src,所以它虽然是非贪婪,但只能匹配到下一个dd的第一个img,所以才会出现1,3,5,7,9这样的问题。

代码

这里我简单的做了注释(注释并不规范)
一个小经验,正则表达式还是写一段测试一段,不然全写完错了,猛的一看有点懵。

# 爬取猫眼电影Top100的电影名称、时间、评分、图片信息,提取的站点的url为http://maoyan.com/board/4结果以文件形式保存下来
# 这里需要美团验证
import requests
import requests.cookies
import re
import json
import time



def get_one_page(url):
    # 利用headers避免403反爬虫
    headers = {
        'Content-Type': 'text/plain; charset=UTF-8',
        'Referer': 'https://maoyan.com/board/4',
        'Origin': 'https://maoyan.com',
        # 不能用Firefox,出现的验证页面暂时无法解决
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    # 指定response的编码
    response.encoding = response.apparent_encoding
    if response.status_code == 200:
        return response.text
    return None


def parse_one_page(html):
    # 不应该全部写好再提取,应该一个一个提取
    # 这里我是醉了,edge的源码显示与其他浏览器的源码显示不一样
    # 还是别以符号作为标志位,容易乱,还是以字母作为标志位
    pattern = re.compile(
        '
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?star">(.*?)

.*?releasetime">(.*?)

.*?score">.*?>(.*?).*?">(.*?)', re.S) items = re.findall(pattern, html) for item in items: #yield就是个return,但是是一次次的返回 关系到生成器 迭代器 yield { 'index': item[0], 'image': item[1], 'title': item[2].strip(), # 如果元组的长度大于3才执行前面的语句,否则返回空.[3:]表示从第三个字符开始 '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() } def write_to_json(content): with open('result.txt', 'a', encoding='utf-8') as f: f.write(json.dumps(content, ensure_ascii=False) + '\n') def main(offset): url = 'https://maoyan.com/board/4?offset='+str(offset) html = get_one_page(url) for item in parse_one_page(html): print(item) write_to_json(item) if __name__ == '__main__': for i in range(10): main(i*10) #睡眠,防止ip被封 time.sleep(2)

结果

爬取TOP100榜猫眼电影信息 爬虫实战_第2张图片
最后附上崔大佬的链接
https://cuiqingcai.com/5534.html

你可能感兴趣的:(爬虫)