Python爬虫项目--爬取猫眼电影Top100榜

                                                                                                                                  本次抓取猫眼电影Top100榜所用到的知识点:

                                                                                                                                  1.?python requests库

                                                                                                                                  2.?正则表达式

                                                                                                                                  3.?csv模块

                                                                                                                                  4.?多进程

                                                                                                                                  正文

                                                                                                                                  目标站点分析

                                                                                                                                  通过对目标站点的分析,?来确定网页结构,?进一步确定具体的抓取方式.

                                                                                                                                  1. 浏览器打开猫眼电影首页,?点击"榜单", 点击"Top100榜",?即可看到目标页面.?

                                                                                                                                  2.??浏览网页, 滚动到下方发现有分页, 切换到第2页, 发现: URL从 http://maoyan.com/board/4变换到http://maoyan.com/board/4?offset=10,?多次切换页码offset都有改变,?可以确定的是通过改变URL的offset参数来生成分页列表.

                                                                                                                                  '''
                                                                                                                                  遇到python不懂的问题,可以加Python学习交流群:1004391443一起学习交流,群文件还有零基础入门的学习资料
                                                                                                                                  '''

                                                                                                                                  项目流程框架:

                                                                                                                                  获取单页源码

                                                                                                                                  #抓取猫眼电影TOP100榜
                                                                                                                                  import requests
                                                                                                                                  import time
                                                                                                                                  from requests.exceptions import RequestException
                                                                                                                                  def get_one_page():
                                                                                                                                      '''获取单页源码'''
                                                                                                                                      try:
                                                                                                                                          url = "http://maoyan.com/board/4?offset={0}".format(0)
                                                                                                                                          headers = {
                                                                                                                                              "User-Agent":"Mozilla/5.0(WindowsNT6.3;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/68.0.3440.106Safari/537.36"
                                                                                                                                          }
                                                                                                                                          res = requests.get(url, headers=headers)
                                                                                                                                          # 判断响应是否成功,若成功打印响应内容,否则返回None
                                                                                                                                          if res.status_code == 200:
                                                                                                                                              print(res.text)
                                                                                                                                          return None
                                                                                                                                      except RequestException:
                                                                                                                                          return None
                                                                                                                                  def main():
                                                                                                                                      get_one_page()
                                                                                                                                  if __name__ == '__main__':
                                                                                                                                      main()
                                                                                                                                      time.sleep(1)

                                                                                                                                  执行即可得到网页源码,?那么下一步就是解析源码了

                                                                                                                                  解析单页源码

                                                                                                                                  导入正则表达式re模块,?对代码进行解析,?得到想要的信息.

                                                                                                                                  import re
                                                                                                                                  
                                                                                                                                  def parse_one_page(html):
                                                                                                                                      '''解析单页源码'''
                                                                                                                                      pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?name"><a.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime'
                                                                                                                                                           + '.*?>(.*?)</p>.*?score.*?integer">(.*?)</i>.*?>(.*?)</i>.*?</dd>',re.S)
                                                                                                                                      items = re.findall(pattern,html)
                                                                                                                                      print(items)
                                                                                                                                      #采用遍历的方式提取信息
                                                                                                                                      for item in  items:
                                                                                                                                          yield {
                                                                                                                                              'rank' :item[0],
                                                                                                                                              'title':item[1],
                                                                                                                                              'actor':item[2].strip()[3:] if len(item[2])>3 else '',  #判断是否大于3个字符
                                                                                                                                              'time' :item[3].strip()[5:] if len(item[3])>5 else '',
                                                                                                                                              'score':item[4] + item[5]
                                                                                                                                          }
                                                                                                                                  def main():
                                                                                                                                      html = get_one_page()
                                                                                                                                      for item in parse_one_page(html):
                                                                                                                                          print(item)
                                                                                                                                  
                                                                                                                                  if __name__ == '__main__':
                                                                                                                                      main()
                                                                                                                                      time.sleep(1)

                                                                                                                                  提取出信息之后,?那么下一步就是保存到文件

                                                                                                                                  保存到文件中

                                                                                                                                  这里采用两种方式,?一种是保存到text文件,?另一种是保存到csv文件中,?根据需要选择其一即可.

                                                                                                                                  1.?保存到text文件

                                                                                                                                  import json
                                                                                                                                  
                                                                                                                                  def write_to_textfile(content):
                                                                                                                                      '''写入到text文件中'''
                                                                                                                                      with open("MovieResult.text",'a',encoding='utf-8') as f:
                                                                                                                                          #利用json.dumps()方法将字典序列化,并将ensure_ascii参数设置为False,保证结果是中文而不是Unicode码.
                                                                                                                                          f.write(json.dumps(content,ensure_ascii=False) + "\n")
                                                                                                                                          f.close()
                                                                                                                                  def main():
                                                                                                                                      html = get_one_page()
                                                                                                                                      for item in parse_one_page(html):
                                                                                                                                          write_to_textfile(item)
                                                                                                                                  
                                                                                                                                  if __name__ == '__main__':
                                                                                                                                      main()
                                                                                                                                      time.sleep(1)

                                                                                                                                  2.?保存到CSV文件

                                                                                                                                  其文件以纯文本的形式存储表格数据

                                                                                                                                  import csv
                                                                                                                                  def write_to_csvfile(content):
                                                                                                                                      '''写入到csv文件中'''
                                                                                                                                      with open("MovieResult.csv",'a',encoding='gb18030',newline='') as f:
                                                                                                                                          # 将字段名传入列表
                                                                                                                                          fieldnames = ["rank", "title", "actor", "time", "score"]
                                                                                                                                          #将字段名传给Dictwriter来初始化一个字典写入对象
                                                                                                                                          writer = csv.DictWriter(f,fieldnames=fieldnames)
                                                                                                                                          #调用writeheader方法写入字段名
                                                                                                                                          writer.writeheader()
                                                                                                                                          writer.writerows(content)
                                                                                                                                          f.close()
                                                                                                                                  def main():
                                                                                                                                      html = get_one_page()
                                                                                                                                      rows = []
                                                                                                                                      for item in parse_one_page(html):
                                                                                                                                          #write_to_textfile(item)
                                                                                                                                          rows.append(item)
                                                                                                                                      write_to_csvfile(rows)
                                                                                                                                  if __name__ == '__main__':
                                                                                                                                      main()
                                                                                                                                      time.sleep(1)

                                                                                                                                  单页的信息已经提取出,?接着就是提取多个页面的信息

                                                                                                                                  获取多个页面

                                                                                                                                  1.?普通方法抓取

                                                                                                                                  def main(offset):
                                                                                                                                      url = "http://maoyan.com/board/4?offset={0}".format(offset)
                                                                                                                                      html = get_one_page(url)
                                                                                                                                      rows = []
                                                                                                                                      for item in parse_one_page(html):
                                                                                                                                          #write_to_textfile(item)
                                                                                                                                          rows.append(item)
                                                                                                                                      write_to_csvfile(rows)
                                                                                                                                  if __name__ == '__main__':
                                                                                                                                      #通过遍历写入TOP100信息
                                                                                                                                      for i in range(10):
                                                                                                                                          main(offset=i * 10)
                                                                                                                                          time.sleep(1)

                                                                                                                                  2.?多进程抓取

                                                                                                                                  from multiprocessing import Pool
                                                                                                                                  
                                                                                                                                  if __name__ == '__main__':
                                                                                                                                      # 将字段名传入列表
                                                                                                                                      fieldnames = ["rank", "title", "actor", "time", "score"]
                                                                                                                                      write_to_csvField(fieldnames)
                                                                                                                                      pool = Pool()
                                                                                                                                      #map方法会把每个元素当做函数的参数,创建一个个进程,在进程池中运行.
                                                                                                                                      pool.map(main,[i*10 for i in range(10)])

                                                                                                                                  ?完整代码

                                                                                                                                  #抓取猫眼电影TOP100榜
                                                                                                                                  '''
                                                                                                                                  遇到python不懂的问题,可以加Python学习交流群:1004391443一起学习交流,群文件还有零基础入门的学习资料
                                                                                                                                  '''
                                                                                                                                  from multiprocessing import Pool
                                                                                                                                  from requests.exceptions import RequestException
                                                                                                                                  import requests
                                                                                                                                  import json
                                                                                                                                  import time
                                                                                                                                  import csv
                                                                                                                                  import re
                                                                                                                                  def get_one_page(url):
                                                                                                                                      '''获取单页源码'''
                                                                                                                                      try:
                                                                                                                                          headers = {
                                                                                                                                              "User-Agent":"Mozilla/5.0(WindowsNT6.3;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/68.0.3440.106Safari/537.36"
                                                                                                                                          }
                                                                                                                                          res = requests.get(url, headers=headers)
                                                                                                                                          # 判断响应是否成功,若成功打印响应内容,否则返回None
                                                                                                                                          if res.status_code == 200:
                                                                                                                                              return res.text
                                                                                                                                          return None
                                                                                                                                      except RequestException:
                                                                                                                                          return None
                                                                                                                                  def parse_one_page(html):
                                                                                                                                      '''解析单页源码'''
                                                                                                                                      pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?name"><a.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime'
                                                                                                                                                           + '.*?>(.*?)</p>.*?score.*?integer">(.*?)</i>.*?>(.*?)</i>.*?</dd>',re.S)
                                                                                                                                      items = re.findall(pattern,html)
                                                                                                                                      #采用遍历的方式提取信息
                                                                                                                                      for item in  items:
                                                                                                                                          yield {
                                                                                                                                              'rank' :item[0],
                                                                                                                                              'title':item[1],
                                                                                                                                              'actor':item[2].strip()[3:] if len(item[2])>3 else '',  #判断是否大于3个字符
                                                                                                                                              'time' :item[3].strip()[5:] if len(item[3])>5 else '',
                                                                                                                                              'score':item[4] + item[5]
                                                                                                                                          }
                                                                                                                                  
                                                                                                                                  def write_to_textfile(content):
                                                                                                                                      '''写入text文件'''
                                                                                                                                      with open("MovieResult.text",'a',encoding='utf-8') as f:
                                                                                                                                          #利用json.dumps()方法将字典序列化,并将ensure_ascii参数设置为False,保证结果是中文而不是Unicode码.
                                                                                                                                          f.write(json.dumps(content,ensure_ascii=False) + "\n")
                                                                                                                                          f.close()
                                                                                                                                  
                                                                                                                                  def write_to_csvField(fieldnames):
                                                                                                                                      '''写入csv文件字段'''
                                                                                                                                      with open("MovieResult.csv", 'a', encoding='gb18030', newline='') as f:
                                                                                                                                          #将字段名传给Dictwriter来初始化一个字典写入对象
                                                                                                                                          writer = csv.DictWriter(f,fieldnames=fieldnames)
                                                                                                                                          #调用writeheader方法写入字段名
                                                                                                                                          writer.writeheader()
                                                                                                                                  def write_to_csvRows(content,fieldnames):
                                                                                                                                      '''写入csv文件内容'''
                                                                                                                                      with open("MovieResult.csv",'a',encoding='gb18030',newline='') as f:
                                                                                                                                          #将字段名传给Dictwriter来初始化一个字典写入对象
                                                                                                                                          writer = csv.DictWriter(f,fieldnames=fieldnames)
                                                                                                                                          #调用writeheader方法写入字段名
                                                                                                                                          #writer.writeheader()            ###这里写入字段的话会造成在抓取多个时重复.
                                                                                                                                          writer.writerows(content)
                                                                                                                                          f.close()
                                                                                                                                  
                                                                                                                                  def main(offset):
                                                                                                                                      fieldnames = ["rank", "title", "actor", "time", "score"]
                                                                                                                                      url = "http://maoyan.com/board/4?offset={0}".format(offset)
                                                                                                                                      html = get_one_page(url)
                                                                                                                                      rows = []
                                                                                                                                      for item in parse_one_page(html):
                                                                                                                                          #write_to_textfile(item)
                                                                                                                                          rows.append(item)
                                                                                                                                      write_to_csvRows(rows,fieldnames)
                                                                                                                                  
                                                                                                                                  if __name__ == '__main__':
                                                                                                                                      # 将字段名传入列表
                                                                                                                                      fieldnames = ["rank", "title", "actor", "time", "score"]
                                                                                                                                      write_to_csvField(fieldnames)
                                                                                                                                      # #通过遍历写入TOP100信息
                                                                                                                                      # for i in range(10):
                                                                                                                                      #     main(offset=i * 10,fieldnames=fieldnames)
                                                                                                                                      #     time.sleep(1)
                                                                                                                                      pool = Pool()
                                                                                                                                      #map方法会把每个元素当做函数的参数,创建一个个进程,在进程池中运行.
                                                                                                                                      pool.map(main,[i*10 for i in range(10)])

                                                                                                                                  ?

                                                                                                                                  展开阅读全文

                                                                                                                                  没有更多推荐了,返回首页