Python 在字符串中使用通配符

Python Using wildcard inside of strings

我正在尝试从 boxofficemoviemojo.com 中删除数据,并且我已正确设置所有内容。但是我收到一个我无法弄清楚的逻辑错误。本质上,我想获取前 100 部电影并将数据写入 csv 文件。

我目前正在使用此站点的 html 进行测试(其他年份相同):http://boxofficemojo.com/yearly/chart/?yr=2014&p=.htm

有很多代码,但这是我正在努力处理的主要部分。代码块如下所示:

def grab_yearly_data(self,page,year):
    # page is the url that was downloaded, year in this case is 2014.

    rank_pattern=r'<td align="center"><font size="2">([0-9,]*?)</font>'
    mov_title_pattern=r'(.htm">[A-Z])*?</a></font></b></td>'
    #mov_title_pattern=r'.htm">*?</a></font></b></td>' # Testing

    self.rank= [g for g in re.findall(rank_pattern,page)]
    self.mov_title=[g for g in re.findall(mov_title_pattern,page)]

self.rank 完美运行。但是 self.mov_title 没有正确存储数据。我想收到一个包含 102 个元素和电影片名的列表。但是我收到 102 个空字符串:''。一旦我弄清楚我做错了什么,程序的其余部分将非常简单,我只是无法在线找到我的问题的答案。我已经多次尝试更改 mov_title_pattern,但我要么什么也没收到,要么收到 102 个空字符串。请帮助我真的很想继续我的项目。

mov_title_pattern=r'.htm">([A-Za-z0-9 ]*)</a></font></b></td>'

尝试 this.This 应该适合您的 case.See 演示。

https://www.regex101.com/r/fG5pZ8/6

你的正则表达式没有多大意义。它匹配 .htm">[A-Z] 的次数越少越好,通常为零,产生一个空字符串。

此外,对于像这样的非常通用的正则表达式,不能保证它只匹配结果行。生成的页面包含许多其他地方,您可以在这些地方找到 .htm"> 后跟一些东西。

更一般地说,我会提倡一种方法,您可以在其中制作一个正则表达式,该正则表达式可以精确标识每个生成的结果行,并从中提取您想要的所有值。换句话说,尝试类似

re.findall('stuff (rank) stuff (title) stuff stuff stuff')

(我把它留作练习,用适当的 HTML 片段设计一个精确的正则表达式,其中我有 stuff 占位符) 并从每个匹配的行中提取 "rank" 组和 "title" 组。

诚然,抓取始终是一项脆弱的工作。如果你让你的正则表达式非常紧凑,如果网站改变了它布局中的一些细节,它很可能会停止工作。如果你让它太放松,它有时会 return 错误的东西。

只是 don't attempt to parse HTML with regex - 它会节省您的时间,最重要的是 - 头发,会让您的生活更轻松。

这是一个使用 BeautifulSoup HTML parser 的解决方案:

from bs4 import BeautifulSoup
import requests

url = 'http://boxofficemojo.com/yearly/chart/?yr=2014&p=.htm'
response = requests.get(url)

soup = BeautifulSoup(response.content)

for row in soup.select('div#body td[colspan="3"] > table[border="0"] tr')[1:-3]:
    cells = row.find_all('td')
    if len(cells) < 2:
        continue

    rank = cells[0].text
    title = cells[1].text
    print rank, title

打印:

1 Guardians of the Galaxy
2 The Hunger Games: Mockingjay - Part 1
3 Captain America: The Winter Soldier
4 The LEGO Movie
...
98 Transcendence
99 The Theory of Everything
100 As Above/So Below

select() 调用中的表达式是 CSS Selector - 一种方便而强大的元素定位方式。但是,由于这个特定页面上的元素不能方便地用 id 映射或用 class 标记,我们必须依赖像 colspanborder 这样的属性。 [1:-3] slice 是用来消除表头和总行的。


对于 this page,要到达 table,您可以依赖图表元素并获取它的下一个 table 兄弟:

for row in soup.find('div', id='chart_container').find_next_sibling('table').find_all('tr')[1:-3]:
    ...