美文网首页Python
python爬虫-猫眼100-requests+正则表达式

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

作者: DKider | 来源:发表于2019-03-22 21:00 被阅读10次

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

最近系统的开始了爬虫的学习,虽然以前也写过不少,但是现在跟着书学,感觉学会了不少,这里来分享一下。
我们今天的目标是猫眼电影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

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

<dd>
                        <i class="board-index board-index-1">1</i>
    <a href="/films/1203" title="霸王别姬" class="image-link" data-act="boarditem-click" data-val="{movieId:1203}">
      <img src="//s0.meituan.net/bs/?f=myfe/mywww:/image/loading_2.e3d934bf.png" alt="" class="poster-default" />
      <img data-src="https://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c" alt="霸王别姬" class="board-img" />
    </a>
    <div class="board-item-main">
      <div class="board-item-content">
              <div class="movie-item-info">
        <p class="name"><a href="/films/1203" title="霸王别姬" data-act="boarditem-click" data-val="{movieId:1203}">霸王别姬</a></p>
        <p class="star">
                主演:张国荣,张丰毅,巩俐
        </p>
<p class="releasetime">上映时间:1993-01-01</p>    </div>
    <div class="movie-item-number score-num">
<p class="score"><i class="integer">9.</i><i class="fraction">5</i></p>        
    </div>

      </div>
    </div>

                </dd>

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

<dd>.*?board-index.*?>(.*?)</i>.*?data-src="('+
        '.*?)".*?"name"><a.*?>(.*?)</a>.*?star">('+
        '.*?)</p>.*?releasetime">(.*?)</p>.*?integer">('+
        '.*?)</i>.*?fraction">(.*?)</i>.*?</dd>

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

def parser_one_page(html):
    '''
    解析一页的10部电影信息
    输入html对象
    输出需要的信息->dict
    <dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?
name.*?a.*?>(.*?)</a>.*?"star">(.*?)</p>.*?releasetime"
>(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>
    '''
    pattern = re.compile('<dd>.*?board-index.*?>(.*?)</i>.*?data-src="('+
                         '.*?)".*?"name"><a.*?>(.*?)</a>.*?star">('+
                         '.*?)</p>.*?releasetime">(.*?)</p>.*?integer">('+
                         '.*?)</i>.*?fraction">(.*?)</i>.*?</dd>', 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
    <dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>.*?"star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>
    '''
    # regex='<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(' \
    #      '.*?)</a>.*?"star">(.*?)</p>.*?"releasetime">(.*?)</p>.*?"integer">(' \
    #      '.*?)</li>.*?"fraction">(.*?)</i>'
    pattern = re.compile('<dd>.*?board-index.*?>(.*?)</i>.*?data-src="('+
                         '.*?)".*?"name"><a.*?>(.*?)</a>.*?star">('+
                         '.*?)</p>.*?releasetime">(.*?)</p>.*?integer">('+
                         '.*?)</i>.*?fraction">(.*?)</i>.*?</dd>', 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+正则表达式

    本文链接:https://www.haomeiwen.com/subject/utfdvqtx.html