码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • Python 爬虫学习之路 第一天


    算法太难,直接来学爬虫

    第一个爬虫程序

    爬取这个网站的所有电影名称,评分,类型,内容简介,封面(只是一个网址)和上映时间

    Scrape | Movie

    网站在上面

    所谓爬虫,就是对于一个网站的爬取,我们先关注url,对于这个网站分为两个,列表页和详情页,因此需要函数去分别提取这两个页的url,所对应的html代码,并且去解析它,最后得到所要的结果。

    因此第一个我们要做的就是对于页面的爬取,以下是代码

    1. # 页面爬取方法
    2. def scrape_page(url):
    3. logging.info('scraping %s...' , url)
    4. try:
    5. response = requests.get(url)
    6. if response.status_code == 200:
    7. return response.text
    8. logging.error('get invalid status code %s while scraping %s', response.status_code, url)
    9. # 异常处理
    10. except requests.RequestException:
    11. # exec_info 可以打印出错误信息
    12. logging.error('error occurred while scraping %s' , url , exec_info = True)

    这个函数所实现的就是,对于一个网址,去爬取它的html代码,我们直接使用get请求即可,如果状态码是200,那么直接返回所对应网址的html代码,否则输出错误日志

    然后需要的就是,对于一种网页进行爬取,先定义列表页

    1. # 列表页的爬取方法
    2. # page 接受page参数
    3. def scrape_index(page):
    4. # https://ssr1.scrape.center/page/2
    5. index_url = f'{BASE_URL}/page/{page}'
    6. return scrape_page(index_url)

    我们可以将固定格式的url列表页进行字符的拼接得到需要的url,最后再使用scrape_page方法,获取这个页面的html代码

    再下来,就是对于每一个列表页解析,得到详情页的url

    1. # 解析列表页
    2. def parse_index(html):
    3. #
    4. pattern = re.compile('')
    5. items = re.findall(pattern, html) # 找到网页中的所有和pattern匹配的内容
    6. if not items:
    7. return []
    8. for item in items:
    9. detail_url = urljoin(BASE_URL, item) # 拼接得到一个完整的详情页
    10. # https://ssr1.scrape.center/detail/1
    11. logging.info('get detail url %s', detail_url)
    12. yield detail_url

    其中使用了非贪婪通用匹配,使用F12调到开发者工具,对于一个详情页所在的超链接存在于href之后,因此需要使用一个括号表示需要匹配得到的属性,因此这个正则表达式表示的就是匹配超链接,然后使用findall获取所有匹配的内容,最后拼接成一个完整的详情页,因此我们就得到了所需要的详情页的url

    接下来,就是爬取详情页。

    通过分析可以得到,每个页面所拥有的信息有电影名称,评分,类型,内容简介,封面(只是一个网址)和上映时间,因此需要先获取html代码,再使用正则表达式匹配每一个信息即可。

    1. # 爬取详情页的数据
    2. def scrape_detail(url):
    3. return scrape_page(url)
    4. def parse_detail(html):
    5. # 匹配cover信息,可以使用compile将正则表达式转换为一个正则表达式对象
    6. # 可以每一次不用重新书写正则表达式
    7. # 封面信息
    8. cover_pattern = re.compile('class="item.*?',re.S)
    9. # 名称信息
    10. name_pattern = re.compile('(.*?)')
    11. # 类别信息
    12. categories_pattern = re.compile('(.*?).*?',re.S)
    13. # 上映时间信息
    14. published_at_pattern = re.compile('(\d{4}-\d{2}-\d{2})\s?上映')
    15. # 某一部电影的内容信息
    16. drama_pattern = re.compile('.*?(.*?)

      '
      ,re.S)
    17. # 评分信息
    18. score_pattern = re.compile('(.*?)

      '
      ,re.S)
    19. # 再对每一个信息进行匹配
    20. # 如果不是特殊的情况基本都使用search
    21. # 使用strip函数获得给定需求
    22. cover = re.search(cover_pattern, html).group(1).strip() if re.search(cover_pattern, html) else None
    23. name = re.search(name_pattern, html).group(1).strip() if re.search(name_pattern, html) else None
    24. # 因为结果可能有多个所以需要使用findall函数返回一个列表
    25. categories = re.findall(categories_pattern, html) if re.findall(categories_pattern, html) else []
    26. published_at = re.search(published_at_pattern, html).group(1) if re.search(published_at_pattern, html) else None
    27. drama = re.search(drama_pattern, html).group(1).strip() if re.search(drama_pattern, html) else None
    28. # 注意score是一个浮点数需要强制转换
    29. score = float(re.search(score_pattern, html).group(1).strip()) if re.search(score_pattern, html) else None
    30. return {
    31. '封面': cover,
    32. '名字': name,
    33. '类别': categories,
    34. '上映时间': published_at,
    35. '内容简介': drama,
    36. '评分': score
    37. }

    这一部分注释写的很详细,不再赘述。

    最后,当然是储存数据

    我还没有学如何转换到数据库中,那就姑且用json文件保存就行,然后使用万能的记事本打开即可。

    1. import json
    2. from os import makedirs
    3. from os.path import exists
    4. RESULTS_DIR = 'results'
    5. # 判断是否存在路径如果存在不用管了 , 如果不存在重新创建一个
    6. exists(RESULTS_DIR) or makedirs(RESULTS_DIR)
    7. import multiprocessing
    8. # ensure_ascii = False 可以保证中文字符在文件中正常输出
    9. # indent 两行缩进
    10. def save_data(data):
    11. name = data.get('名字')
    12. data_path = f'{RESULTS_DIR}/{name}.json'
    13. json.dump(data, open(data_path, 'w', encoding='utf-8'),ensure_ascii=False, indent=2)

    然后就是主函数

    有两种表达方法,第一种就是毫无优化的爬取,也就是一个一个网页进行爬取,最终得到每个电影的信息,第二种就是优化版本,用多进程加速,将每个页码放入进程池中,让电脑的cpu进行加速,就比如说,4核电脑,python默认有4个进程同时进行,实现加速

    第一种

    1. def main():
    2. for page in range(1 , TOTAL_PAGE + 1):
    3. index_html = scrape_index(page) # 得到列表页的url
    4. detail_urls = parse_index(index_html) # 得到详情页的url
    5. # 遍历整个详情页的url 然后提取每一个url的信息 最后输出即可
    6. for detail_url in detail_urls:
    7. detail_html = scrape_detail(detail_url)
    8. data = parse_detail(detail_html)
    9. logging.info('get detail data %s', data)
    10. logging.info('saving data to json file')
    11. save_data(data)
    12. logging.info('data saved successfully')
    13. # logging.info('detail urls %s', list(detail_urls))
    14. if __name__ == '__main__':
    15. main()

    第二种

    1. def main(page):
    2. index_html = scrape_index(page)
    3. detail_urls = parse_index(index_html)
    4. for detail_url in detail_urls:
    5. detail_html = scrape_detail(detail_url)
    6. data = parse_detail(detail_html)
    7. logging.info('get detail data %s', data)
    8. logging.info('saving data to json file')
    9. save_data(data)
    10. logging.info('data saved successfully')
    11. if __name__ == '__main__':
    12. pool = multiprocessing.Pool()
    13. pages = range(1, TOTAL_PAGE + 1)
    14. pool.map(main, pages)
    15. pool.close()

    以上就是第一个爬虫程序

    如果代码有问题,可以提出来一起学习。

    以下是运行结果

     

  • 相关阅读:
    `英语` 2022/8/18
    基于A2C与超启发式的航天器星载自主任务规划算法-笔记
    易基因-原核转录组“rRNA捕获探针及其应用“方法获发明专利授权
    HiveSql调优系列之Hive严格模式,如何合理使用Hive严格模式
    Allegro原理图反标教程
    输入ceph命令无效,进入ceph shell界面就有效是正常的吗?
    LeetCode每日一题——1758. 生成交替二进制字符串的最少操作数
    【C语言 数据结构】顺序表的使用
    CSS补充
    【TensorFlow2 之012】TF2.0 中的 TF 迁移学习
  • 原文地址:https://blog.csdn.net/xp_xht123/article/details/126732271
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号