python爬虫-猫眼100-requests+正则表达式

周天我也没课的,您给安排一下吧!:)——致某某某

最近系统的开始了爬虫的学习,虽然以前也写过不少,但是现在跟着书学,感觉学会了不少,这里来分享一下。
我们今天的目标是猫眼电影top100
将要用到的库:

import re
import requests
import time
import json
from requests.exceptions import RequestException

网址——https://maoyan.com/board/4,用浏览器打开:

image.png

这是猫眼首页,我们需要的信息在这里都可以看到——电影排名、电影图片、电影名、主演、上映时间、评分。

这次我没用BeautifulSoup库来解析html,用的是正则表达式,刚好学过,就赶紧试用了下。打开网页后按F12,打开开发者工具,在调试一栏中打开源码。不要在查看器、element里查看,因为这里面的可能是JavaScript渲染过后的文件,并不是我们得到的响应源码。


dd

经过观察,我们要的信息在

...
标签里,经过一下午的反复练习,我想出来一个正则表达式的快速写法:先把保存着我们要的信息的
...
标签直接拿出来:

1 霸王别姬

霸王别姬

主演:张国荣,张丰毅,巩俐

上映时间:1993-01-01

9.5

然后将我们要的信息改成: (.?),找到标志位,将其余字符全部用:.? 替代。
如下:

.*?board-index.*?>(.*?).*?data-src="('+ '.*?)".*?"name">(.*?).*?star">('+ '.*?)

.*?releasetime">(.*?)

.*?integer">('+ '.*?).*?fraction">(.*?).*?

所以就有了我们的解析页面的函数:

def parser_one_page(html):
    '''
    解析一页的10部电影信息
    输入html对象
    输出需要的信息->dict
    
.*?board-index.*?>(.*?).*?data-src="(.*?)".*? name.*?a.*?>(.*?).*?"star">(.*?)

.*?releasetime" >(.*?)

.*?integer">(.*?).*?fraction">(.*?) ''' pattern = re.compile('
.*?board-index.*?>(.*?).*?data-src="('+ '.*?)".*?"name">(.*?).*?star">('+ '.*?)

.*?releasetime">(.*?)

.*?integer">('+ '.*?).*?fraction">(.*?).*?
', re.S) items = re.findall(pattern, html) for i in items: yield { 'index': i[0], 'image': i[1], 'name': i[2], 'actor': i[3].strip()[3:], 'releasetime': i[4].strip()[5:], 'score': i[5]+i[6], }

前面要获取首页源码:

def get_one_page(url):
    '''
    获取猫眼top100的一页源码
    输入网页url
    输出源码'''
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0)'
                          ' Gecko/20100101 Firefox/66.0'}
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            print(200)
            return response.text
        return None
    except RequestException:
        return None

然后是将其保存到文件:

def write_to_file(content):
    '''将处理完成的文件放到
    输入处理好的内容
    将内容存储到文件'''
    with open('result.txt', 'a', encoding='utf-8') as f:
        f.write(json.dumps(content, ensure_ascii=False) + '\n')

main函数:

def main(offset):
    '''输入每一页的偏移量'''
    url = "https://maoyan.com/board/4?offset="+str(offset)
    html = get_one_page(url)
    contents = parser_one_page(html)
    for item in contents:
        print(item)
        write_to_file(item)

我发现换页后url多了一个偏移量offset,每页10部电影,即第一页从0开始,第二页从10开始,一次类推,得出:0,10,20,......,90,一共10页,我们写个循环:

if __name__ == "__main__":
    for i in range(10):
        main(i*10)
        time.sleep(1)

因为猫眼有反爬机制,访问速度过快,会被禁止访问,所以我们用了1s的延时。

运行后的成果:


输出
result.txt

这次我们用的是requests库,这比urllib好用很多,用了正则表达式代替beautifulsoup,用了json数据格式来存储数据,非常简单,正则表达式很强大!几乎万能,就是当式子较长后比较闹心。
就这样!

全部代码:

import re
import requests
import time
import json
from requests.exceptions import RequestException

def get_one_page(url):
    '''
    获取猫眼top100的一页源码
    输入网页url
    输出源码'''
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0)'
                          ' Gecko/20100101 Firefox/66.0'}
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            print(200)
            return response.text
        return None
    except RequestException:
        return None

def parser_one_page(html):
    '''
    解析一页的10部电影信息
    输入html对象
    输出需要的信息->dict
    
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?).*?"star">(.*?)

.*?releasetime">(.*?)

.*?integer">(.*?).*?fraction">(.*?) ''' # regex='
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(' \ # '.*?).*?"star">(.*?)

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

.*?"integer">(' \ # '.*?).*?"fraction">(.*?)' pattern = re.compile('
.*?board-index.*?>(.*?).*?data-src="('+ '.*?)".*?"name">(.*?).*?star">('+ '.*?)

.*?releasetime">(.*?)

.*?integer">('+ '.*?).*?fraction">(.*?).*?
', re.S) items = re.findall(pattern, html) for i in items: yield { 'index': i[0], 'image': i[1], 'name': i[2], 'actor': i[3].strip()[3:], 'releasetime': i[4].strip()[5:], 'score': i[5]+i[6], } def write_to_file(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) contents = parser_one_page(html) for item in contents: print(item) write_to_file(item) if __name__ == "__main__": for i in range(10): main(i*10) time.sleep(1)

闲话我不放pyq了。只放,免得受您一顿批。

你可能感兴趣的:(python爬虫-猫眼100-requests+正则表达式)