爬取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
    edge
    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(
        '<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?score">.*?>(.*?)</i>.*?">(.*?)</i>',
        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)

结果

在这里插入图片描述
最后附上崔大佬的链接
https://cuiqingcai.com/5534.html

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值