设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
查看: 38062|回复: 29
打印 上一主题 下一主题

Python 实战(7):连连看

[复制链接]

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

跳转到指定楼层
楼主
发表于 2015-5-31 23:42:04 |只看该作者 |正序浏览
上次课在详细页面上加了海报。除此之外,数据库里还有其他很多信息我们没有用上,比如演员和导演。这些信息还有个重要的作用,就是把不同的影片关联起来。比如你看了一部电影,对其主演感兴趣,自然就想知道他还演过什么影片。现在,我们就来用演员信息把不同的影片连起来。

仔细看过之前抓取豆瓣影片信息的代码就会发现,豆瓣 API 中是以列表形式提供演员和导演信息。而我在抓取时,将其简化,只是选取了其中的姓名,用逗号(,)拼接起来,作为一个字符串存储在数据库中。因此,如果只是想显示出这些信息,可以简单地实现:

<p>主演:$movie.casts</p>

不过现在我们不仅仅要显示主演的名字,还希望能通过主演关联到其他影片。所以这里需要把这些名字分开,并分别加上超链接。

之前课程中说过,web.py 模板可以让你在 HTML 里写 Python。我们现在就需要在模板里对主演名称的字符串做一些处理:

$ casts = movie.casts.split(',')
<p>主演:
$for cast in casts:
    <a href="">$cast</a>
</p>

$ 符号开头的代码将会以 Python 的语法执行。需要特别注意的是,$ casts 之间有一个不可缺少的空格,这个空格说明这里是定义了一个新的变量 casts,而不是获取变量 casts 的值。

通过 split 方法将主演名字拆分成一个字符串列表,再通过 for 循环,将其中每一项拿出,加上 a 标签,做成一个超链接。超链接的地址暂时为空,我们还没有能够处理点击演员名的合适页面。

此时刷新页面,可以看到详细页面上已有了演员信息,并且每个名字下面有一个下划线。只是点击之后并不会有特别的反应。

我们是通过在页面模板中处理演员信息,当然你也可以选择另一种方法,即在后台的响应函数,也就是 class movie 的 GET 方法中,将演员信息处理好,作为额外一项参数传递给模板。

那么接下来的问题,点击了演员名称之后要如何处理。我的想法是进行一次搜索,搜索所有影片演员信息中包含此演员名的电影。因为我们的演员信息是一个字符串存储的,所以可以采用之前搜影片名称类似的方法进行。这样会比较省事,但不足之处是,无法区分名字相同或部分相同的情况。而搜索结果的显示,则可以直接复用 index 模板。

首先在 url 里添加跳转规则:

urls = (
    '/', 'index',
    '/movie/(.*)', 'movie',
    '/cast/(.*)', 'cast',
)

然后是处理的方法:

class cast:
    def GET(self, cast_name):
        condition = r'casts like "%' + cast_name + r'%"'
        movies = db.select('movie', where=condition)
        return render.index(movies)

此处的 GET 方法和 index 里的 POST 方法差不多,唯一不同只是把搜索条件从 title 改为 casts。

最后,再把新增的跳转地址加入到刚刚空着的 a 标签里:

<a href="/cast/$cast">$cast</a>

这里几个名称都用了“cast”,别搞混了。为了区分对于,你也可以分别改为其他名字 cast_name、url_cast、cast_value 等。

这样就已完成演员名的搜索。现在再点击演员名,就可以跳转到搜索结果的页面。

然而,这时候你很可能发现,点击搜索出的结果,并不能再跳转到其他电影的页面(至少我这里是这样)。看了一下,页面被跳转去了

http://127.0.0.1:8080/cast/movie/123456

而不是预想的

http://127.0.0.1:8080/movie/123456

查了代码,原来 问题出在 a 标签的 href 属性上:

"movie/$movie['id']"

前面没有加 /,是表示当前页面下的 movie/xxx 地址,而加了 / 才表示主域名下的 movie/xxx 地址。之前都是从主域名下进行搜索,跳转不会有问题了,而现在一旦使用在 /casts 页面下,跳转就不对了。只要多加上 /,改为

<a href="/movie/$movie['id']">$movie['title']</a>

就没有问题了。

以同样的方式,可以再把导演信息加入搜索功能,这里就不再赘述,各位自行完成。

试着搜了下,发现豆瓣的 top250 里还是比较偏重华语片和老片的。比如张国荣的有 8 部,而克里斯蒂安·贝尔只有 2 部。

code.py (1.16 KB, 下载次数: 297)
movie.html (450 Bytes, 下载次数: 188)



#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

30#
发表于 2018-11-15 21:27:24 |只看该作者
Min1001 发表于 2018-11-15 17:26
请问一下为什么有些人名信息打开正常,有些为什么却是下面这种情况呢

从这个信息我也看不出来

你最好定位下报错放生在哪段代码,并把报错前的相关变量值print出来看看有没有什么异常
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

12

积分

新手上路

Rank: 1

29#
发表于 2018-11-15 17:26:05 |只看该作者
请问一下为什么有些人名信息打开正常,有些为什么却是下面这种情况呢

QQ图片20181115092332.png (81.62 KB, 下载次数: 517)

QQ图片20181115092332.png

回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

28#
发表于 2018-5-17 22:41:33 |只看该作者
skybeak 发表于 2018-5-16 11:15
在这个方法中,def GET(self, director_name):
通过打印  director_name 的值为  å¼—兰克·å ...

还是编码的问题,但不通过调试,我也很难看出是哪里的问题。公众号回复 编码 ,有几篇文章

是的
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

148

积分

注册会员

Rank: 2

27#
发表于 2018-5-16 11:15:32 |只看该作者
在这个方法中,def GET(self, director_name):
通过打印  director_name 的值为  å¼—兰克·德拉邦特
转换成utf-8后显示的是:b'\xc3\xa5\xc2\xbc\xc2\x97\xc3\xa5\xc2\x85\xc2\xb0\xc3\xa5\xc2\x85\xc2\x8b\xc3\x82\xc2\xb7\xc3\xa5\xc2\xbe\xc2\xb7\xc3\xa6\xc2\x8b\xc2\x89\xc3\xa9\xc2\x82\xc2\xa6\xc3\xa7\xc2\x89\xc2\xb9'
这个还是转换编码不对么?转换成utf-8后是不是应该是 具体的人名才对?
另外方法中 director_name的值是来自于movie.html中的<a href="/director/$director">$director</a>的$director么?
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

26#
发表于 2018-5-16 09:41:51 |只看该作者
skybeak 发表于 2018-5-15 11:35
您好:
     我用的是python35,
class director:

如果你是用windows,你可能需要全部都指明为 gbk 会好些
这个编码问题可能很多。建议你先用英文把程序调通
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

148

积分

注册会员

Rank: 2

25#
发表于 2018-5-15 11:35:27 |只看该作者
您好:
     我用的是python35,
class director:
    def GET(self, director_name):
        condition = r'directors like "%' + director_name + r'%"'
        movies = db.select('moviee', where=condition)
        return render.index5(movies)
时,无法搜索到相应的内容;
class director:
    def GET(self, director_name):
        director_name = ‘具体的某个名字时’
        condition = r'directors like "%' + director_name + r'%"'
        movies = db.select('moviee', where=condition)
        return render.index5(movies)
时,可以显示相应的内容。
       我感觉是编码方式的问题,错误'gbk' codec can't decode byte 0xa2 in position 268: illegal multibyte sequence,想请教下老师解决方法。
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

24#
发表于 2018-5-14 22:59:53 |只看该作者
2894386560 发表于 2018-5-14 16:28
404 not found  的错误找到了。。。然后改完之后点击导演的链接就会出现和点击演员的链接一样的错误了… ...

大概是中文编码问题
建议修改下代码,不要通过演员名字,而是通过一个id来对应演员
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

1

主题

0

好友

43

积分

新手上路

Rank: 1

23#
发表于 2018-5-14 16:28:00 |只看该作者
2894386560 发表于 2018-5-14 16:23
先生,我碰到个问题,点击演员的链接的时候有的演员链接可以正常跳转到电影,有的跳转不了会出现图3的错误 ...

404 not found  的错误找到了。。。然后改完之后点击导演的链接就会出现和点击演员的链接一样的错误了……
回复

使用道具 举报

1

主题

0

好友

43

积分

新手上路

Rank: 1

22#
发表于 2018-5-14 16:23:49 |只看该作者
先生,我碰到个问题,点击演员的链接的时候有的演员链接可以正常跳转到电影,有的跳转不了会出现图3的错误,错误的代码是图1,有点搞不懂。
然后导演的链接都显示404 not found ,这个的错误还没能找到。

3.png (9.84 KB, 下载次数: 516)

图3

图3

1.png (60.27 KB, 下载次数: 512)

图1

图1

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即加入

QQ|手机版|Archiver|Crossin的编程教室 ( 苏ICP备15063769号  

GMT+8, 2024-11-22 23:44 , Processed in 0.020724 second(s), 28 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部