Python进阶之Scrapy抓取阳光政务平台
1. 目标
-
- 爬取http://wz.sun0769.com/political/index/politicsNewest
-
- 网站标题及详情内容
2. 页面分析
- 1.列表页网址http://wz.sun0769.com/political/index/politicsNewest?id=1&page=1
通过修改page={}来改变页面,列表内容网页源码中有。
本程序通过找到翻页键实现找到下一页链接发起请求实现翻页。 - 2.详情页网址可以通过检查获取href进行拼接
//ul[@class=‘title-state-ul’]//li/span[3]/a/@href - 3.详情页内容可以通过pre标签获得
3. 示例代码
1. 创建项目
scrapy startproject sunSpider
cd sunSpider
scrapy genspider sun sun0769.com
2. start.py
from scrapy import cmdline
# cmdline.execute(['scrapy','crawl','sun'])
cmdline.execute('scrapy crawl sun'.split())
3. items.py
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
# 字段名一定要在items里边定义,防止正式程序写错
class SunspiderItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
href = scrapy.Field()
content = scrapy.Field()
4. settings.py
BOT_NAME = 'sunSpider'
SPIDER_MODULES = ['sunSpider.spiders']
NEWSPIDER_MODULE = 'sunSpider.spiders'
LOG_LEVEL = 'WARNING'
DEFAULT_REQUEST_HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}
ITEM_PIPELINES = {
'sunSpider.pipelines.SunspiderPipeline': 300,
}
5. pipelines.py
from itemadapter import ItemAdapter
import re
class SunspiderPipeline:
def process_item(self, item, spider):
item['content'] = self.parse_content(item['content'])
print(item)
return item
# 定义一个方法处理格式问题
# 用正则记得导入模块
def parse_content(self,content):
content = re.sub(r'\r\n','',content)
return content
6. sun.py
import scrapy
# 设置目录根,导入item中的类
from sunSpider.items import SunspiderItem
import time
class SunSpider(scrapy.Spider):
name = 'sun'
allowed_domains = ['sun0769.com']
# 确定初始页面为http://wz.sun0769.com/political/index/politicsNewest?id=1&page={}
start_urls = ['http://wz.sun0769.com/political/index/politicsNewest?id=1']
def parse(self, response):
li_list = response.xpath('sc')
for li in li_list:
# 创建类的实例对象
item = SunspiderItem()
# 用.extract_first()获取不带标签的文本数据
item['title'] =li.xpath('./span[3]/a/text()').extract_first()
item['href'] = 'http://wz.sun0769.com' + li.xpath('./span[3]/a/@href').extract_first()
# print(item)
# 向详情页发起请求并返回数据
# 设置数据访问间隔,否则会被反爬
time.sleep(3)
yield scrapy.Request(
url=item['href'],
callback=self.parse_detail,
# 传递字典数据
meta={'item':item}
)
# 找到翻页键对应url,开始进行翻页
next_url = 'http://wz.sun0769.com' + response.xpath(
'//div[@class="mr-three paging-box"]/a[2]/@href').extract_first()
# print(next_url)
if next_url is not None:
yield scrapy.Request(
url=next_url,
# 数据重新丢给parse重新处理
callback=self.parse,
)
def parse_detail(self,response):
# 获取字典中的数据
item = response.meta.get('item')
# 获取详情页数据
item['content'] = response.xpath('//div[@class="details-box"]/pre/text()').extract_first()
# print(item)
yield item
4. 注意事项
- 1.sun.py中字典的创建是导入items里的类,通过创建类的实例对象来创建的
- 2.sun.py中的字段要与items里设置的相同,未设置的需要进行设置
- 3.items的导入要设置项目为根原目录,才能直接.item import 方式导入,否则要根据文件夹顺序逐层.进去
- 4.熟记.extarct_first(),实现取出不含标签文本的功能
- 5.采取翻页的方法进入下一页可以简化代码,但是会比人工设置访问页面的方法增加一些页面的点击。快速的页面点击会导致反爬,注意使用的时候要设置延时时间。