我正试图从Reddit的壁纸subreddit获得最热门的壁纸.我使用beautiful soup
,以获得HTML
第一壁纸的布局,然后regex
获得URL
从锚标记.但通常我会得到一个与我的正则表达式不匹配的URL.这是我正在使用的代码:
r = requests.get("https://www.reddit.com/r/wallpapers") if r.status_code == 200: print r.status_code text = r.text soup = BeautifulSoup(text, "html.parser") search_string = str(soup.find('a', {'class':'title'})) photo_url = str(re.search('[htps:/]{7,8}[a-zA-Z0-9._/:.]+[a-zA-Z0-9./:.-]+', search_string).group())
它有什么办法吗?
这是一个更好的方法:在Reddit中
添加.json
到url的末尾返回一个对象而不是.
例如,将提供HTML内容,但会为您提供一个json对象,您可以使用python中的模块轻松利用它json
HTML
https://www.reddit.com/r/wallpapers
https://www.reddit.com/r/wallpapers/.json
json
这是获得最热门壁纸的相同程序:
>>> import urllib >>> import json >>> data = urllib.urlopen('https://www.reddit.com/r/wallpapers/.json') >>> wallpaper_dict = json.loads(data.read()) >>> wallpaper_dict['data']['children'][1]['data']['url'] u'http://i.imgur.com/C49VtMu.jpg' >>> wallpaper_dict['data']['children'][1]['data']['title'] u'Space Shuttle' >>> wallpaper_dict['data']['children'][1]['data']['domain'] u'i.imgur.com'
如果reddit改变它的HTML布局或有人发布你的正则表达式无法处理的URL,它不仅会更清洁,它还可以防止你头疼.
作为一个拇指规则,使用json
而不是刮取HTML
PS 通常更聪明:里面的列表[children]
是壁纸编号.第一个是最顶层,第二个是第二个,依此类推.因此,['data']['children'][2]['data']['url']
将为您提供第二个最热壁纸的链接.你得到了要点?:)
PPS:更重要的是,使用此方法,您可以使用默认urllib
模块.通常,当你正在抓取时,Reddit
你必须创建假User-Agent
标头并在请求时传递它(或者它给你一个429响应代码,但这不是这种方法的情况.