Python小白逆袭大神 作业二
这个是我个人的理解吧,希望能帮助您们。也是我自己的一个总结吧。
作业内容:
1.请在代码中提示位置,补充代码,完成《青春有你2》选手图片爬取,将爬取图片进行保存,保证代码正常运行 2.打印爬取的所有图片的绝对路径,以及爬取的图片总数,此部分已经给出代码。请在提交前,一定要保证有打印结果。
点击进去会有很多代码,但是这里就指分析一下作业部分,先看下程序的主体:
看代码从主函数看起,可以更清楚程序在做什么,主函数就是代码开始运行的地方,这里代码是从crawl_wiki_data这个函数运行的,运行这个函数意思就是执行上面定义的crawl_wiki_data函数的代码。主函数运行了五个函数,最后的print也是函数,print就跟上面的函数一样,不过它里面的代码不是我们写的。
if __name__ == '__main__':
#爬取百度百科中《青春有你2》中参赛选手信息,返回html
html = crawl_wiki_data()
#解析html,得到选手信息,保存为json文件
parse_wiki_data(html)
#从每个选手的百度百科页面上爬取图片,并保存
crawl_pic_urls()
#打印所爬取的选手图片路径
show_pic_path('/home/aistudio/work/pics/')
print("所有信息爬取完成!")
我们看到其实时四个函数,print不算的话。第一个代码就是在运行第一个函数crawl_wiki_data(),html是返回值,就是这个函数的最终计算的结果放在了这个变量里。
我在主函数里只运行这个函数,打印一下html这个变量的类型:
html = crawl_wiki_data()
print(type(html))
print(html)
运行结果:
这里的200是第一个函数里的第22行有个输出语句print(response.status_code),代表爬取成功,运行的时候可以注释掉。这里看到html的内容其实就是网页中的存储选手信息的表格的代码,就是下图所示对应的代码:
可以在找到这个网页,按下f12,查看这部分的代码,其实就是返回值html的内容。
第二句是parse_wiki_data(html),就是利用第一个函数的返回值html作为第二个函数的参数,第二句运行的函数没有像第一句的返回值,它的运算结果是直接生成json文件存放在work文件夹下面了。所以看一下这个文件夹的内容:
oot":109 items
[100 items
0:{8 items
“name”:string"刘亚楠"
“link”:string"https://baike.baidu.com/item/%E5%88%98%E4%BA%9A%E6%A5%A0/24271343"
“zone”:string"中国湖北"
“constellation”:string"白羊座"
“height”:string"168cm"
“weight”:string"46kg"
“flower_word”:string"西兰花-看起来和吃起来的味道一样就像我将情绪都挂脸上"
“company”:string"华谊兄弟"
}
这个json文件里是第一个函数运行结果的处理,其实都还有选手的信息,只是第二个函数在这里做了数据的处理。
看看第三个函数,也就是要写作业的地方,crawl_pic_urls(),这个函数也没有返回值,运行结果就是把下载的图片放到了work文件夹下面。
def crawl_pic_urls():
'''
爬取每个选手的百度百科图片,并保存
'''
with open('work/'+ today + '.json', 'r', encoding='UTF-8') as file:
json_array = json.loads(file.read())
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
for star in json_array:
name = star['name']
link = star['link']
#!!!请在以下完成对每个选手图片的爬取,将所有图片url存储在一个列表pic_urls中!!!
#向选手的链接发送请求
response = requests.get(link,headers=headers)
#将服务器传过来的文档利用BeautifulSoup的构造方法,得到一个文档对象
bs = BeautifulSoup(response.text,'lxml')
#从个人页面中解析一个指向选手图片的链接
pic_list_url = bs.select('.summary-pic a')[0].get('href')
pic_list_url = 'https://baike.baidu.com'+pic_list_url
pic_list_response = requests.get(pic_list_url,headers=headers)
bs = BeautifulSoup(pic_list_response.text,'lxml')
pic_list_html = bs.select('.pic-list img')
#获取要下载图片的地址 存储在pic_urls列表中
pic_urls = []
for pic_html in pic_list_html:
pic_url = pic_html.get('src')
pic_urls.append(pic_url)
#!!!根据图片链接列表pic_urls, 下载所有图片,保存在以name命名的文件夹中!!!
这个是这个函数的完整代码。
with open('work/'+ today + '.json', 'r', encoding='UTF-8') as file:
json_array = json.loads(file.read())
这两句代码是打开第二个函数生成的json文件,并且用json.loads函数来加载,存在列表变量json_array里面。
json_arrat里面的内容格式是:
[{‘name’: ‘刘亚楠’, ‘link’: ‘https://baike.baidu.com/item/%E5%88%98%E4%BA%9A%E6%A5%A0/24271343’, ‘zone’: ‘中国湖北’, ‘constellation’: ‘白羊座’, ‘height’: ‘168cm’, ‘weight’: ‘46kg’, ‘flower_word’: ‘西兰花-看起来和吃起来的味道一样就像我将情绪都挂脸上’, ‘company’: ‘华谊兄弟’},{下一位选手的信息},…]
下面的headers就是一个请求服务器响应必要的东西,就是来模仿人进行访问。
下面是一个for循环,来访问每个明星的信息。
for star in json_array:
这里用第一次循环为例进行分析,第一次循环star的值是:
{‘name’: ‘刘亚楠’, ‘link’: ‘https://baike.baidu.com/item/%E5%88%98%E4%BA%9A%E6%A5%A0/24271343’, ‘zone’: ‘中国湖北’, ‘constellation’: ‘白羊座’, ‘height’: ‘168cm’, ‘weight’: ‘46kg’, ‘flower_word’: ‘西兰花-看起来和吃起来的味道一样就像我将情绪都挂脸上’, ‘company’: ‘华谊兄弟’}
name = star['name']
link = star['link']
这句执行完后name 的值为 ‘刘亚楠’ ,link的值为 ‘https://baike.baidu.com/item/%E5%88%98%E4%BA%9A%E6%A5%A0/24271343’
response = requests.get(link,headers=headers)
#将服务器传过来的文档利用BeautifulSoup的构造方法,得到一个文档对象
bs = BeautifulSoup(response.text,'lxml')
这两句就是把上面link网址所对应的网页代码存储起来,放到bs中。这个页面的样子是这样的:
#从个人页面中解析一个指向选手图片的链接
pic_list_url = bs.select('.summary-pic a')[0].get('href')
pic_list_url = 'https://baike.baidu.com'+pic_list_url
这里过去的是右边图册点击进去的网址。可以通过f12看到右边图册的链接是在summary-pic 下面的。但是链接的网址不是全的:
所以这里前面加上网址补全了网址,就是第二句干的事情。
pic_list_response = requests.get(pic_list_url,headers=headers)
bs = BeautifulSoup(pic_list_response.text,'lxml')
pic_list_html = bs.select('.pic-list img')
这三句代码跟上面干的事情有点像了,先是获取有选手图片的网站的代码,就是这样的网站:
pic_list_html存的是包含了选手多张图片链接的代码,其中还有别的无关的代码,所以用一个for循环,将每张照片的链接分别存储起来,放在pic_urls列表中:
pic_urls = []
for pic_html in pic_list_html:
pic_url = pic_html.get('src')
pic_urls.append(pic_url)
至此作业部分就完成了,后面就是调用 down_pic(name,pic_urls)函数根据刚刚的获取的图片链接进行下载。