urllib模块(旧)

简介

requests模块:python中原生的一款基于网络请求的模块,功能非常强大,简单便捷,效率极高。
作用:模拟浏览器发请求。

使用(request模块的编码流程)

  1. 指定url
  2. 发起请求(get/post)
  3. 获取响应数据
  4. 持久化存储

安装:pip install request

实战

需求:爬取搜狗首页的页面数据

  1. # 初尝试
  2. import requests
  3. if __name__ == "__main__":
  4. # step1:指定url
  5. url = "https://zhihu.sogou.com/"
  6. # step2:发起请求
  7. # get方法会返回一个响应对象
  8. response = requests.get(url=url,)
  9. # step3:获取响应数据,响应数据在响应对象里,需要请求成功
  10. #text 返回的是字符串形式的响应数据
  11. page_text = response.text
  12. print(page_text)
  13. # step4:持久化存储
  14. with open('./sougou.html', 'w', encoding='utf-8') as fp:
  15. fp.write(page_text)

实战巩固

  1. 需求:爬取搜狗指定词条对应的搜索结果页面(简易网页采集器)
  2. 需求:破解百度翻译
  3. 需求:爬取豆瓣电影分类排行榜https://movie.douban.com/中的电影详情数据
  4. 需求:爬取肯德基餐厅查询http://www.kfc.com.cn/kfccda/index.aspx中指定地点的餐厅数据
  5. 需求:爬取国家药品监督管理总局中基于中华人民共和国化妆品生产许可证相关数据http://scxk.nmpa.gov.cn:81/xk/

网易采集器

搜狗输入一个关键字,然后对页面进行抓取
UA检测与伪装
UA:User-Agent

  1. import requests
  2. # UA:User-Agent(请求载体的身份标识)
  3. # UA检测:门户网站的服务器会检测对应请求的载体身份标识,如果检测到的身份标识为某一款浏览器,
  4. # 说明该请求为正常请求。若检测为不是,则为不正常请求(爬虫)。服务器端则可能拒绝此次请求。
  5. # UA伪装:让爬虫对应的请求载体身份标识伪装成某一款浏览器
  6. if __name__ == "__main__":
  7. # UA伪装:将对应的User-Agent封装到一个字典中
  8. headers = {
  9. 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Mobile Safari/537.36 Edg/100.0.1185.29'
  10. }
  11. url = 'https://www.sogou.com/web'
  12. # 处理url携带的参数:封装到字典中
  13. kw = input('enter a word:')
  14. param = {
  15. 'query': kw
  16. }
  17. # 对指定的url发起的请求对应的url是携带参数的,并且请求过程中处理了参数
  18. response = requests.get(url=url, params=param, headers=headers)
  19. page_text = response.text
  20. fileName = kw + '.html'
  21. with open(fileName, 'w', encoding='utf-8') as fp:
  22. fp.write(page_text)
  23. print(fileName, 'save success!!')

破解百度翻译

对应单词或句子的翻译结果
爬取局部数据
什么是xhr?
什么是AJAX请求?ajax 是一种浏览器通过 js 异步发起请求, 局部更新页面的技术。
xhr,全称为XMLHttpRequest,用于与服务器交互数据,是ajax功能实现所依赖的对象,jquery中的ajax就是对 xhr的封装。
局部刷新,ajax请求,就是对应的单字翻译结果

  1. import requests
  2. # 只拿到翻译结果
  3. # 页面局部刷新,用ajax请求
  4. # post请求(携带了参数)
  5. # 响应数据是一组json数据
  6. import json
  7. if __name__ == "__main__":
  8. post_url = 'https://fanyi.baidu.com/sug'
  9. # post请求参数处理(同get一致)
  10. word = input('enter a word:')
  11. data = {
  12. 'kw': word
  13. }
  14. # 进行UA伪装
  15. headers = {
  16. 'User-Agent': 'Mozilla / 5.0(Windows NT 10.0;Win64;x64;rv: 99.0) Gecko / 20100101Firefox / 99.0'
  17. }
  18. response = requests.post(url=post_url, data=data, headers=headers)
  19. # 响应数据是一组json数据,json返回的是一个对象obj,(如果确认服务器响应数据是json类型的,才可以使用json)
  20. # content-type可以看到类型
  21. dict_obj = response.json()
  22. print(dict_obj)
  23. # 持久化存储
  24. file_Name = word + '.json'
  25. fp = open(file_Name, 'w', encoding='utf-8')
  26. json.dump(dict_obj, fp=fp, ensure_ascii=False)

豆瓣电影

爬取排行榜里喜剧,电影的作者等等。
当前页面局部的信息,不用数据解析如何爬取?
是否有ajax请求呢?
当滚轮到底部的时候发起了ajax请求
是不是有了ajax请求,加上参数就行了

  1. import requests
  2. import json
  3. if __name__ == "__main__":
  4. url = 'https://movie.douban.com//j/chart/top_list'
  5. headers = {
  6. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0'
  7. }
  8. # https://movie.douban.com/typerank?type_name=%E5%96%9C%E5%89%A7&type=24&interval_id=100:90&action=
  9. # 问号后的都是参数
  10. params = {
  11. 'type': '24',
  12. 'interval_id': '100:90',
  13. 'action': '',
  14. 'start': '80', # 从库中第几部开始去取
  15. 'limit': '20', # 一次取多少个
  16. }
  17. response = requests.get(url=url, headers=headers, params=params)
  18. list_obj = response.json()
  19. fp = open('./douban.json', 'w', encoding='utf-8')
  20. json.dump(list_obj, fp=fp, ensure_ascii=False)
  21. print('success')

作业:肯德基餐厅查询

需求:爬取肯德基餐厅查询http://www.kfc.com.cn/kfccda/index.aspx中指定地点的餐厅数据
点按钮如果网址变了, 那就不是ajax请求。
局部刷新就是ajax请求,只要参数就行。

image.png

  1. import requests
  2. import json
  3. if __name__ == "__main__":
  4. url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
  5. headers = {
  6. 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Mobile Safari/537.36 Edg/100.0.1185.29'
  7. }
  8. addre = input('请输入查询地点:')
  9. params = {
  10. 'cname': "",
  11. 'pid': "",
  12. 'keyword': addre,
  13. 'pageIndex': "1",
  14. 'pageSize': "10",
  15. }
  16. response = requests.post(url=url, headers=headers, params=params)
  17. # Content - Type:text / plain;charset = utf - 8
  18. list_obj = response.text
  19. with open('./KFC.text', 'w', encoding='utf-8') as fp:
  20. fp.write(list_obj)
  21. print('success')

综合练习—药监总局

image.png

  1. 需求:爬取国家药品监督管理总局中基于中华人民共和国化妆品生产许可证相关的数据,http://scxk.nmpa.gov.cn:81/xk/

详情页面
image.png
将上面这组数据爬取下来。


首先对http://scxk.nmpa.gov.cn:81/xk/这个发起请求,响应数据是否包含企业的数据?
image.png
是没有包含相关信息的,并不是由url直接得到。
验证是否由ajax得到。
image.png发现响应里没有具体企业的信息。
存在动态加载数据,直接由url发起得不到。

每一个企业名称对应的是一个超链接,想获得详情页所对应的超链接,


动态加载数据

image.png
image.png
首页数据由ajax动态请求得到。
详情页的url由首页里的数据获得。

http://scxk.nmpa.gov.cn:81/xk/itownet/portal/dzpz.jsp?id=6ea7eab68c88455f945552e95faab678
id由首页数据获得,不同企业的ID不同,由ID可拼接出详情页的URL。
image.png
详情页也得验证是不是动态数据。发下详情页数据也是动态加载,不能直接对url发起请求得到数据。

—所有的post请求的url都是一样的,只有参数id值是不同。
—如果我们可以批量获取多家企业的id后,就可以将id和url形成一个完整的详情页对应详情数据的ajax请求的URL

  1. import requests
  2. import json
  3. if __name__ == "__main__":
  4. headers = {
  5. 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Mobile Safari/537.36 Edg/100.0.1185.29'
  6. }
  7. id_list = [] # 存储企业的ID
  8. # 批量获取不同企业ID值
  9. url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
  10. # 参数的封装
  11. for page in range(1, 6):
  12. page = str(page)
  13. data = {
  14. 'on': 'true',
  15. 'page': page, # 页码,改动态
  16. 'pageSize': '15',
  17. 'productName': '',
  18. 'conditionType': '1',
  19. 'applyname': '',
  20. 'applysn': '',
  21. }
  22. json_ids = requests.post(url=url, headers=headers, data=data).json()
  23. for dic in json_ids['list']:
  24. id_list.append(dic['ID'])
  25. # 获取企业详情数据
  26. all_data_list = [] # 存储所以企业详情数据
  27. post_url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
  28. for id in id_list:
  29. data = {
  30. 'id': id
  31. }
  32. detail_json = requests.post(url=post_url, headers=headers, data=data).json()
  33. print(detail_json, '---------------ending----------')
  34. all_data_list.append(detail_json)
  35. # 持久化存储数据
  36. fp = open('./allDate.json', 'w', encoding='utf-8')
  37. json.dump(all_data_list, fp=fp, ensure_ascii=False)