朝小闇的博客

海上月是天上月,眼前人是心上人

爬虫之Scrapy(2.实战)

1.新建项目yangguang

1.1 新建项目

1
2
scrapy startproject yangguang
cd yangguang # 进入新建项目列表

1.2 新建爬虫文件

1
scrapy genspider yg wz.sun0769.com

1.3 初始化

  • 更改start_urls
1
start_urls = ['http://wz.sun0769.com/political/index/politicsNewest?id=1&page=1/']
  • 在settings.py文件中添加日志过滤配置:
1
LOG_LEVEL = "WARNING"
  • (重要!!!)在settings.py文件中添加下载限速配置(笔者由于下载过快直接导致整个宿舍的ip被网站封了……):
1
2
# 0.5是每次下载间隔0.5s
DOWNLOAD_DELAY = 0.5
  • 写入访问请求头的用户代理(每个网站都不同,打开netWork随便选中一个链接都可看到):
1
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'

2.items.py

  • (分析网页)在items.py文件中定义字典元素:
1
2
3
4
5
6
7
8
class YangguangItem(scrapy.Item):
# define the fields for your item here like:
status = scrapy.Field() # 状态
title = scrapy.Field() # 标题
href = scrapy.Field() # 链接地址
publish_date = scrapy.Field() # 发布时间
content_img = scrapy.Field() # 内容图片
content_text = scrapy.Field() # 内容文本
  • yg.py爬虫文件中导入刚刚定义的字典元素:
1
from yangguang.items import YangguangItem

3.正式爬取

3.1 分组爬取列表页内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def parse(self, response):
# 分组
url = "http://wz.sun0769.com"
li_list = response.xpath('//*[@class="title-state-ul"]/li')

for li in li_list:
item = YangguangItem() # 实例化
item["status"] = li.xpath('./*[@class="state2"]/text()').extract_first()
item["title"] = li.xpath('./*[@class="state3"]/a/text()').extract_first()
item["href"] = li.xpath('./*[@class="state3"]/a/@href').extract_first()
item["publish_date"] = li.xpath('./*[@class="state5 "]/text()').extract_first()

# href 不完整
item["href"] = url + str(item["href"])
print(item["href"])

yield scrapy.Request(
str(item["href"]),
callback=self.parse_detail,
meta={"item": item} # 将item数据通过meta传输给下一个处理函数
)

3.2 进一步爬取内容详情页

1
2
3
4
5
6
7
8
9
10
def parse_detail(self, response):
item = response.meta["item"] # 按照键值对的形式接收meta传过来的数据
# 文本内容和图片都可能不止一段或一张
item["content_text"] = response.xpath('//*[@class="details-box"]/pre/text()').extract()
item["content_img"] = response.xpath('//*[@class="clear details-img-list Picture-img"]/img/@src').extract()

# 如果图片链接不完整,执行以下语句(上述图片地址完整):
# item["content_img"] = ["http://wz.sun0769.com"+i for i in item["content_img"]]

print(item["title"])

3.3 在parse函数最后实现翻页请求

1
2
3
4
5
6
7
8
9
10
# 翻页
next_url = response.xpath('//*[@class="arrow-page prov_rota"]/@href').extract_first()
next_url = url + next_url
# if next_url is not None:
# 这里直接从101跳到了第一页,所以不用上述
if response.xpath('//*[@class="mr-three paging-box"]/a[4]/text()') != "3":
yield scrapy.Request(
next_url,
callback=self.parse
)

3.4 pipelines.py

1
2
3
4
5
6
7
8
9
10
11
12
13
import re

class YangguangPipeline:
def process_item(self, item, spider):
item["content_img"] = self.content_process(item["content_img"])
item["content_text"] = self.content_process(item["content_text"])
return item

def content_process(self, content):
# re不太会用,可以百度
content = [re.sub(r"\xa0|\s", "", i) for i in content]
content = [i for i in content if len(i) > 0] # 去除列表中的空字符串
return content

4.结果显示

image-20200913213413120

-------- 本文结束 感谢阅读 --------