01. 使用Scrapy实现数据爬取完整流程

1.1 创建新片场爬虫

1.1.1 创建并用PyCharm打开爬虫

  • 进入工程指定的目录,使用scrapy startproject命令生成爬虫。 ```python

    进入项目目录

    (base) D:>cd Project\Python

创建一个名为XPCScrapy的工程。

(base) D:\Project\Python>scrapy startproject XPCScrapy New Scrapy project ‘XPCScrapy’, using template directory ‘C:\ProgramData\Anaconda3\lib\site-packages\scrapy\templates\project’, created in: D:\Project\Python\XPCScrapy

You can start your first spider with: cd XPCScrapy scrapy genspider example example.com

  1. - 此时,Scrapy项目的根目录为:`D:\Project\Python\XPCScrapy`
  2. - 使用PyCharm打开Scrapy项目的根目录(D:\Project\Python\XPCScrapy)。
  3. <a name="pAlz5"></a>
  4. #### 1.1.2 配置settings文件
  5. - 初始化settings.py文件,主要修改ROBOTSTXT_OBEYDOWNLOAD_DELAYDEFAULT_REQUEST_HEADERS三个字段的值。
  6. ```python
  7. ROBOTSTXT_OBEY = False
  8. DOWNLOAD_DELAY = 1
  9. DEFAULT_REQUEST_HEADERS = {
  10. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  11. 'Accept-Language': 'en',
  12. }

1.1.3 创建爬虫程序

  • 创建新片场爬虫:

    1. (base) D:\Project\Python\XPCScrapy>scrapy genspider xpc www.xinpianchang.com
    2. Created spider 'xpc' using template 'basic' in module:
    3. XPCScrapy.spiders.xpc
  • 我们需要爬取的是广告页面中的内容,因此还需要将spiders/xpc.py文件中的XpcSpider类的start_urls属性改为新片场广告页面的地址。

    1. class XpcSpider(scrapy.Spider):
    2. name = 'xpc'
    3. allowed_domains = ['www.xinpianchang.com']
    4. start_urls = ['https://www.xinpianchang.com/discover/article-1-0-all-all-0-0-hot?from=navigator']
    5. def parse(self, response):
    6. pass

    1.2 使用Scrapy提取数据

    1.2.1 xpath()使用XPath提取数据

  • parse()回调函数中的response可以直接调用xpath()函数来通过XPath提取数据。

  • 示例:提取广告页面的所有标题。

    1. def parse(self, response):
    2. for div in response.xpath('//*[@id="__next"]/section/main/div/div[3]/div'):
    3. title = div.xpath('./div/div[2]/div[1]/a/h2/text()')
    4. print(title)
  • 编写完成后,可以通过scrapy crawl xpc来运行这个新片场爬虫。

  • 运行后,其中的一条数据为:[<Selector xpath='./div/div[2]/div[1]/a/h2/text()' data='《同感》美的人感科技'>]

    1.2.2 extract_first()/extract()/get()提取匹配数据

  • 从1.2.1的运行结果中可以看出,XPath提取的结果格式为:[<Selector xpath='XPath路径' data='提取到的数据'>]

  • 可以通过extract_first()/extract()/get()这三个函数提取data中的数据:
    • extract_first():返回xpath()结果中的第一项,并将其作为字符串返回。如果找不到匹配项,则返回None。
    • extract():返回xpath()查询结果中所有项,并以列表形式返回。如果未找到匹配项,则返回一个空列表。
    • get():与extract_first()类似,但是它只返回一个具体的值,而不是字符串或None。当匹配了多个元素时,只返回第一个匹配项的内容。
  • 总的来说,extract_first()extract()适用于需要多次处理的xpath()查询结果,而get()通常用于只需要获取单个值的场景。
  • 示例:获取广告页面的所有标题、对应的详情页链接、分类信息。

    1. def parse(self, response):
    2. for div in response.xpath('//*[@id="__next"]/section/main/div/div[3]/div'):
    3. title = div.xpath('./div/div[2]/div/a/h2/text()').extract_first() # 标题
    4. detail_page_url = div.xpath('./div/div[2]/div/a/@href').extract_first() # 详情页链接
    5. category = div.xpath('./div/div[2]/div[2]/div/div/div/text()').extract_first() # 分类信息
    6. print(title, detail_page_url, category)

    1.2.3 在Scrapy中使用其他提取技术(以BeautifulSoup为例)

  • 在Scrapy中要使用BeautifulSoup来提取数据,可以先通过response.text获取响应的源码,然后再用源码构建BS对象。

  • 构建完BS对象之后,所有的操作都与之前requests + bs4完全一致。
  • 示例:利用BS4提取广告页面的所有标题、对应的详情页链接、分类信息。 ```python

    导入BeautifulSoup模块

    from bs4 import BeautifulSoup

def parse(self, response):

  1. # 构建BeautifulSoup对象
  2. soup = BeautifulSoup(response.text, 'html.parser')
  3. # 提取数据
  4. for div in soup.select('main > div > div:nth-child(3) > div'):
  5. title = div.select_one('div > div:nth-child(2) > div > a > h2').text # 标题
  6. detail_page_url = div.select_one('div > div:nth-child(2) > div > a').attrs['href'] # 详情页链接
  7. category = div.select_one('div > div:nth-child(2) > div:nth-child(2) > div > div').text # 分类信息
  8. print(title, detail_page_url, category)
  1. <a name="dlOML"></a>
  2. ### 1.3 封装Item
  3. - Spiders中的数据提取完成后,会封装成Item。因此在正式存储数据之前,需要在items.py文件中编写Item。
  4. - 自定义Item是一个继承自`scrapy.Item`类,Item属性的定义方式为:`属性名 = scrapy.Field()`。
  5. - Item的结构由实际爬取的数据结构决定,如1.2中我们获取了title、detail_page_url、category三个字段的数据,这三个字段构成了广告的基本信息。
  6. - 那么由此就可以在items.py文件中定义一个XpcBaseItem的类,然后在这个类中声明title、detail_page_url、category这三个属性。
  7. ```python
  8. class XpcBaseItem(scrapy.Item):
  9. title = scrapy.Field()
  10. detail_page_url = scrapy.Field()
  11. category = scrapy.Field()
  • 接着,就可以回到回调函数中,将提取完成的数据封装成Item。 ```python

    引入定义好的Item结构

    from XPCScrapy.items import XpcBaseItem

修改回调函数中的内容。

def parse(self, response): for div in response.xpath(‘//*[@id=”__next”]/section/main/div/div[3]/div’):

  1. # 提取数据。
  2. title = div.xpath('./div/div[2]/div/a/h2/text()').extract_first() # 标题
  3. detail_page_url = div.xpath('./div/div[2]/div/a/@href').extract_first() # 详情页链接
  4. category = div.xpath('./div/div[2]/div[2]/div/div/div/text()').extract_first() # 分类信息
  5. # 构建一个Item,并向里面填充数据。
  6. # 填充格式为:`Item变量[Item所拥有的字段] = 数据`
  7. item = XpcBaseItem()
  8. item['title'] = title
  9. item['detail_page_url'] = detail_page_url
  10. item['category'] = category
  11. # Item分装完成后,利用yield关键字将Item还给引擎。
  12. # 引擎接下去会将Item传递给Item Pipeline。
  13. yield item
  1. <a name="ON0nX"></a>
  2. ### 1.4 Pipeline数据存储
  3. - Item封装完成后,会进入Item Pipeline进行数据清洗与验证,最后实现存储。
  4. - 因此,在pipelines.py中,可以编写数据的清洗、验证与存储逻辑。
  5. - Pipeline是一个普通的自定义类,但这个自定义类一定存在一个`process_item(self, item, spider)`函数。
  6. - 这个函数有且仅有self、item、spider三个参数,并且最后会将item返回。
  7. - Item的清洗、验证与存储逻辑就写在`process_item()`中。
  8. ```python
  9. import csv
  10. class XpcPipeline:
  11. def process_item(self, item, spider):
  12. with open('./advertisement.csv', 'a', encoding='utf-8', newline='') as file:
  13. csv_writer = csv.writer(file)
  14. csv_writer.writerow((
  15. item.get('title'),
  16. item.get('detail_page_url'),
  17. item.get('category')
  18. ))
  19. return item
  • 在Pipeline定义完成后,需要在settings.py文件的ITEM_PIPELINES字典中注册Pipeline。

    • 若没有在ITEM_PIPELINES中注册Pipeline,则该Pipeline不会生效。
    • ITEM_PIPELINES中注册Pipeline的格式:Pipeline的位置: 优先级
      1. ITEM_PIPELINES = {
      2. 'XPCSpider.pipelines.XpcPipeline': 300,
      3. }
  • 当上述所有步骤完成后,一个最基本的爬虫程序(数据爬取、数据提取、数据存储)就完成了。

  • 此时就可以通过scrapy crawl xpc来运行爬虫程序了。

    02. 新片场爬虫项目(多请求与多Item处理)(06. 使用Scrapy完成新片场爬取 05:17)

  • 爬取新片场广告页面的数据

    • 爬取多页数据:10页。
    • 广告页面:详情页连接。
    • 详情页:爬取广告的标题、点赞数、收藏数。
    • 其他:电影的播放地址、评论数据。









  • 阿斯顿

    03. Scrapy爬虫基本开发流程总结

  • 创建工程:scrapy startproject PROJECT_NAME

  • settings.py文件的基本配置。
  • 创建爬虫:需要进入到PROJECT_NAME路径中,执行scrapy genspider SPIDER_NAME SPIDER_DOMAIN命令。
  • 编写爬虫(SPIDER_NAME.py):编写start_urls起始地址、编写下一个请求、编写数据提取。
  • 在items.py文件中编写数据存储结构。
  • 在pipelines.py文件的process_item中编写数据处理与存储逻辑,并去settings.py中注册pipelines。
  • 启动爬虫:scrapy crawl SPIDER_NAME