|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 一轮江月明 于 2017-4-7 08:04 编辑
我是跟着崔老师的视频一步一步走的,https://edu.hellobi.com/course/156/lessons
注释很多,都是自己的理解,应该大部分都是对的吧,请各位看出问题的不吝赐教。
有个问题就是,程序不能正确执行,我只是想下载图片到电脑里就行了,现在总是抓不对。
关于求助:
1、一定要提供代码源代码文本,不要只贴图片。(有源码)
2、一定要贴出完整报错信息。(最崩溃的是没有报错信息,是下载了几张图片,可是完全不是那个页面的. 我是新手小白,用pycharm还不会调试,也是被自己笨的哭死了)
3、操作系统,是mac,还是Linux,还是windows。(win)
4、Python 2还是Python 3。(py3)
5、一定要描述清楚,提出问题前,看看自己写的是不是清楚明白。
- import requests
- from json.decoder import JSONDecodeError
- import os
- import json
- import re
- from bs4 import BeautifulSoup
- #import pymongo
- from requests.exceptions import RequestException
- from urllib.parse import urlencode
- #from config import *
- #from hashlib import md5
- #from multiprocessing import Pool
- """
- client = pymongo.MongoClient(MONGO_URL,connect=False)
- db = client[MONGO_DB]
- """
- def get_page_index(offset, keyword):
- data = {
- 'offset': offset,
- 'format': 'json',
- 'keyword': keyword,
- 'autoload': 'true',
- 'count': '20',
- 'cur_tab': 3
- }
- url = 'http://www.toutiao.com/search_content/?' + urlencode(data)
- print(url)
- '''
- 结果是
- url = http://www.toutiao.com/search_content/?offset=0&format=json&keyword=%E8%A1%97%E6%8B%8D&autoload=true&count=20&cur_tab=3
- 但是通过这个url只得到了一个json格式的对象,不能得到我们想要的街拍的那个网址(http://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D),
- 通过街拍这个网址得到的又是‘综合’,并不是我们想要的‘图集’
- 故不能用soup =BeautifulSoup(url.text,'html.parser'),用soup.select('J_title')的方法来得到各个图集的链接地址
- '''
- try:
- response = requests.get(url)
- if response.status_code == 200:
- return response.text #返回结果是一个字符串
- return None
- except RequestException:
- print('请求索引页出错!')
- return None
-
- def parse_page_index(html): # 由json对象data得到各图集的地址,并不是由列表页得到各图集的地址,因为没有访问列表页
- try:
- data = json.loads(html) # html是一个字符串,data是一个json的对象
- if data and 'data' in data.keys(): # 如果data不为空并且有key:data
- for item in data.get('data'): # json对象获取字典中键对应值的方法是get,如果是字典,可以直接用dict['key']
- yield item.get('article_url') # 得到各图集第一副图的地址
- except JSONDecodeError: # json对象为空可能引起的一些错误或者警告
- pass
- def get_page_detail(url): #访问每个图集的第一副图的地址
- try:
- response = requests.get(url)
- if response.status_code == 200:
- return response.text
- return None
- except RequestException:
- print('请求索引页出错!')
- return None
-
- def save_image(content,title,num): # 参数是二进制的图片
- '''
- file_path = '{0}/{1}.{2}'.format(os.getcwd(),md5(content).hexdigest(),'jpg')#每张图片得到一个md5的摘要值,如果图片一样,md5值也会一样
- '''
- file_path = '{0}/{1}.{2}'.format(os.getcwd(),title + '-'+str(num),'jpg')
- if not os.path.exists(file_path):
- with open(file_path,'wb') as f:
- f.write(content)
- f.close()
- def download_image(url,title,num): #别忘了这个url的内容只有一张图片哦
- print('正在下载',url)
- try:
- response = requests.get(url)
- if response.status_code == 200:
- save_image(response.content,title,num) #response.text是返回网页的正常显示内容,content是返回二进制内容,一般网页的返回用text,图片的返回用content
- return None
- except RequestException:
- print('请求图片页出错!')
- return None
- def parse_page_detail(html, url):#在每个图集的第一副图的地址,即这个页面中找到图集的标题,以及图集所有图片的url
- #通过这个url可以真正的访问到第一副图,就可以用beautifulsoup了
- soup = BeautifulSoup(html, 'lxml') #用lxml来解析
- title = soup.select('title')[0].get_text() #得到网页标签页的标题,一般被title标签包裹(注意不是网页正文内的大标题,
- #正文内的大标题一般被h1或者h2类似的标签包裹),最后如果是.text也可以,
- #一种用属性,一种用方法
- print(title)
- '''
- import requests
- res =requests.get('http://www.toutiao.com/a6402374724713808129/#p=1')
- soup = BeautifulSoup(res.text, 'lxml')
- title = soup.select('title')[0].text #这样可以得到标签页title
- title_pattern = re.compile('<title>(.*?)</title>')
- title_result = re.search(title_pattern,res.text) #可以直接写title_result = re.search('<title>(.*?)</title>',res.text)
- title_result.group(1) #这样也可以得到标签页title
- '''
- images_pattern = re.compile('var gallery = (.*?);', re.S) # 建立要寻找的字符串的正则表达式模型
- result = re.search(images_pattern, html) # 寻找所有符合模型的字符串
- if result: # 如果result不为空
- data = json.loads(result.group(1)) # result.group(1)也是一个json对象,包含图片集中每张图片的地址,但是仔细观察会发现,地址有很多重复的,这是怎么回事呢,真的是重复的么?
- if data and 'sub_images' in data.keys(): #字典中得到键的列表集合也是dict1.keys()
- sub_images = data.get('sub_images') #通过观察结果发现sub_images是一个列表,内容都是字典,有几张图片就有几个字典,字典的第一个键是url
- images = [item.get('url') for item in sub_images] #images也是一个列表,有几张图片就有几个元素,元素都是url,注意这个url里面的内容只有一张图片
- num = 0
- for image in images:
- num += 1
- download_image(image,title,num)
- return {
- 'title': title, #标签页标题
- 'url': url, #第一副图的地址
- 'images': images #这个图集的地址列表
- }
-
- def save_to_mongo(result):
- if db[MONGO_TABLE].insert(result):
- print('存储到MongoDB成功',result)
- return True
- return False
-
- def main(offset):
- html = get_page_index(offset, '街拍') # 该访问得到一个包含有个图集地址的json对象(并不是图集列表页)(是图集,不是综合或者视频)的内容,
- # html是一个json对象(不是图集列表页)
- for url in parse_page_index(html): # 由json对象data得到各图集第一副图的地址url
- html = get_page_detail(url) # 获取各图集第一副图url的正文
- if html: # 如果html不为空
- result = parse_page_detail(html, url)
- '''
- if result:save_to_mongo(result)
- '''
- if __name__ == '__main__':
- main(0)
复制代码 |
|