爬取猫眼电影,多方式解析(正则表达式、XPath、Beautiful Soup、Pyquery)

本文介绍了使用四种不同方法从猫眼电影排行榜抓取电影数据的过程。通过正则表达式、XPath、BeautifulSoup及Pyquery实现了对电影排名、标题、主演、上映时间和评分等信息的有效抓取,并对每种方法进行了对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主函数都一样,只是解析的方式(parse_one_page)不一样

效果:

1 霸王别姬 主演:张国荣,张丰毅,巩俐 上映时间:1993-01-01(中国香港) 9.6
2 肖申克的救赎 主演:蒂姆·罗宾斯,摩根·弗里曼,鲍勃·冈顿 上映时间:1994-10-14(美国) 9.5
3 罗马假日 主演:格利高里·派克,奥黛丽·赫本,埃迪·艾伯特 上映时间:1953-09-02(美国) 9.1
4 这个杀手不太冷 主演:让·雷诺,加里·奥德曼,娜塔莉·波特曼 上映时间:1994-09-14(法国) 9.5
5 教父 主演:马龙·白兰度,阿尔·帕西诺,詹姆斯·肯恩 上映时间:1972-03-24(美国) 9.3
6 泰坦尼克号 主演:莱昂纳多·迪卡普里奥,凯特·温丝莱特,比利·赞恩 上映时间:1998-04-03 9.5
7 龙猫 主演:日高法子,坂本千夏,糸井重里 上映时间:1988-04-16(日本) 9.2
8 唐伯虎点秋香 主演:周星驰,巩俐,郑佩佩 上映时间:1993-07-01(中国香港) 9.2
9 魂断蓝桥 主演:费雯·丽,罗伯特·泰勒,露塞尔·沃特森 上映时间:1940-05-17(美国) 9.2
10 千与千寻 主演:柊瑠美,入野自由,夏木真理 上映时间:2001-07-20(日本) 9.3
11 乱世佳人 主演:费雯·丽,克拉克·盖博,奥利维娅·德哈维兰 上映时间:1939-12-15(美国) 9.1
12 喜剧之王 主演:周星驰,莫文蔚,张柏芝 上映时间:1999-02-13(中国香港) 9.2
13 天空之城 主演:寺田农,鹫尾真知子,龟山助清 上映时间:1992 9.1
14 大闹天宫 主演:邱岳峰,毕克,富润生 上映时间:1965-12-31 9.0
15 辛德勒的名单 主演:连姆·尼森,拉尔夫·费因斯,本·金斯利 上映时间:1993-12-15(美国) 9.2
16 音乐之声 主演:朱莉·安德鲁斯,克里斯托弗·普卢默,埃琳诺·帕克 上映时间:1965-03-02(美国) 9.0
17 春光乍泄 主演:张国荣,梁朝伟,张震 上映时间:1997-05-30(中国香港) 9.2

一、正则表达式

import json
import requests
from requests.exceptions import RequestException
import re
import time
def get_one_page(url):
    headers = {
        'User-Agent':'Mozilla/5.0 (Macintosh;Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko)\
    Chrome/52.0.2743.116 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    if response.status_code == 200:
        return response.text
    return None

def parse_one_page(html):
    pattern = re.compile('<dd>.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>.*?star.*?>(.*?)</p>.*?releasetime.*?>(.*?)</p>.*?integer.*?>(.*?)</i>.*?fraction.*?>(.*?)</i>.*?</dd>',re.S)
    items = re.findall(pattern,html)
    for item in items:
        yield {
            'index':item[0],
            'image':item[1],
            'title':item[2].strip(),
            '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()
        }
        print(item)

def write_to_file(content):
    with open('result.txt','a',encoding='utf-8') as f:
        print(type(json.dumps(content)))
        f.write(json.dumps(content,ensure_ascii=False)+'\n')
        
def main(offset):
    url = "http://maoyan.com/board/4?offset="+str(offset)
    html = get_one_page(url)
    for item in parse_one_page(html):
        write_to_file(item)

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

二、XPath

import requests
from lxml import etree
import time
def get_one_page(url):
    headers = {
        'User-Agent':'Mozilla/5.0 (Macintosh;Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko)\
    Chrome/52.0.2743.116 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    if response.status_code == 200:
        return response.text
    return None

def parse_xpath(html):
    html = etree.HTML(html)
    results = html.xpath('//dd')
    for result in results:
        rank = result.xpath('i/text()')[0].strip()
        title = result.xpath('div//p[1]/a/@title')[0].strip()
        star = result.xpath('div//p[2]/text()')[0].strip()
        releasetime = result.xpath('div//p[3]/text()')[0].strip()
        score_0 = result.xpath('div/div/div/p/i[1]/text()')[0].strip()
        score_1 = result.xpath('div/div/div/p/i[2]/text()')[0].strip()
        score = score_0+score_1
        print(rank,title,star,releasetime,score)
    return result
        
def main(offset):
    url = "http://maoyan.com/board/4?offset="+str(offset)
    html = get_one_page(url)
    aa = parse_xpath(html)

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

三、Beautiful Soup

def get_one_page(url):
    headers = {
        'User-Agent':'Mozilla/5.0 (Macintosh;Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko)\
    Chrome/52.0.2743.116 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    if response.status_code == 200:
        return response.text
    return None


def parse_xpath(html):
    soup = BeautifulSoup(html,'lxml')
    for i,movie in enumerate(soup.dl.contents):
        if movie!="\n":
            rank = movie.i.text
            title = movie.a["title"]
            star = movie.div.div.div.find_all(class_='star')[0].string.strip()
            releasetime = movie.div.div.div.find_all(class_='releasetime')[0].string.strip()
            score = movie.div.div.find_all(class_='integer')[0].string.strip()+movie.div.div.find_all(class_='fraction')[0].string.strip()
            print(rank,title,star,releasetime,score)

def main(offset):
    url = "http://maoyan.com/board/4?offset="+str(offset)
    html = get_one_page(url)
    aa = parse_xpath(html)

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


四、Pyquery    


import requests
from pyquery import PyQuery as pq
import time
def get_one_page(url):
    headers = {
        'User-Agent':'Mozilla/5.0 (Macintosh;Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko)\
    Chrome/52.0.2743.116 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    if response.status_code == 200:
        return response.text
    return None

def parse_xpath(html):
    doc = pq(html)
    dds = doc('.board-wrapper dd').items()
    for dd in dds:
        content = dd.text().split("\n")
        rank = dd.text().split("\n")[0]
        title = dd.text().split("\n")[1]
        star = dd.text().split("\n")[2]
        releasetime = dd.text().split("\n")[3]
        score = dd.text().split("\n")[4]
        print(rank,title,star,releasetime,score)
        
def main(offset):
    url = "http://maoyan.com/board/4?offset="+str(offset)
    html = get_one_page(url)
    aa = parse_xpath(html)

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

首先,需要明确的是,下厨房网站的数据结构可能会变化,这可能导致直接使用XPath正则表达式无法直接获取到所需信息。不过,我会为你展示如何使用BeautifulSoup从下厨房抓取数据的基本步骤。由于实际URL和HTML结构未提供,我将假设一个示例URL和HTML结构。 对于基于BeautifulSoup的获取: ```python import requests from bs4 import BeautifulSoup # 假设这是下厨房的页面URL url = "https://www.xiachufang.com/recipe/top_recipes" # 发送GET请求 response = requests.get(url) html_content = response.text # 使用BeautifulSoup解析HTML soup = BeautifulSoup(html_content, 'html.parser') # 查找特定元素,如菜名、食材等,可能需要根据实际网页结构调整 recipe_cards = soup.find_all('div', class_='recipe-card') # 假设是这个类名 for card in recipe_cards: title = card.find('h2', class_='title')['data-title'] # 获取菜名,通常在标标签内有属性"data-title" ingredients = card.find('span', class_='ingredients') # 食材在span标签内,假设类名为"ingredients" link = card.find('a')['href'] # 链接在<a>标签内的href属性 author = card.find('p', class_='author')['data-username'] # 作者可能在p标签内,有"data-username"属性 print(f"菜名:{title}") print(f"食材:{ingredients.strip()}") print(f"链接:{link}") print(f"作者:{author}\n") ``` 对于使用XPath: ```python import requests from lxml import etree from urllib.parse import urljoin # ... (同上) ... def get_xpath_data(response): html_doc = etree.HTML(response.text) recipes = html_doc.xpath('//div[@class="recipe-card"]') for recipe in recipes: title = recipe.xpath('./h2[@class="title"]/@data-title')[0] ingredients = recipe.xpath('./span[@class="ingredients"]/text()')[0].strip() link = urljoin(url, recipe.xpath('./a/@href')[0]) author = recipe.xpath('./p[@class="author"]/@data-username')[0] yield { "title": title, "ingredients": ingredients, "link": link, "author": author } # ... (同上) ... for data in get_xpath_data(response): # 打印数据 print(data) ``` 对于使用正则表达式,由于HTML的复杂性和不确定性,这种方法通常不是最佳选择,但如果确实能找到稳定的匹配模式,可以尝试: ```python import re import requests # ... (同上) ... pattern_title = r'data-title="(.*?)"' pattern_ingredients = r'<span class="ingredients">(.*?)</span>' pattern_author = r'data-username="(.*?)"' recipe_data = {} response = requests.get(url) content = response.text titles = re.findall(pattern_title, content) ingredients = re.findall(pattern_ingredients, content) authors = re.findall(pattern_author, content) i = 0 for _ in range(len(recipe_cards)): recipe_data["title"] = titles[i] recipe_data["ingredients"] = ingredients[i].strip() recipe_data["link"] = "..." # 此处应根据实际情况替换,比如使用findall后的链接 recipe_data["author"] = authors[i] print(recipe_data) i += 1 ``` 请注意,上述代码中的某些部分需要根据实际下厨房网页结构调整。如果你能提供具体的HTML片段,我可以提供更精确的帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值