scrapy+selenium+IE爬取行政处罚信息公示表遇到的坑

用scrapy爬取某官网的行政处罚信息公示表,先从官网的某省市分站进行数据抓取,批量下载了行政处罚文书文档,这个过程遇到了好几个坑,下载到的文档打开后结果还是乱码的。新手上路的我,现说说难点,希望走过路过的各位大神,能够帮忙指点一下迷津,不胜感激。
目标网页及数据:
第一层网
第二层网页:
第二层网页
第一坑:网站上右键点击可以查看到详情页的链接地址和原码,但是scrapy返回的response是空的,只有网站的框架结构代码。F12调用开发人员工具,找不到详情页的链接和内容。
绕道,使用selenium+IE,返回的browser.page_source出现了详情页的链接地址。
第二坑:对browser.page_source使用xpath无法提取详情页的链接地址,可能是browser.page_source的格式问题,无法用xpath定位,IE用F12调用开发人员工具,无法显示和复制xpath,应该是我的水平问题实在看不清那么长的代码。百度,用格式化工具我也看不清详情页的链接地址的句柄,提取路径。无奈,最后用正值表达式,两次筛选后,得到了详情页的链接地址。

['/guangzhou/129142/129159/129166/4165418/index.html']
['/guangzhou/129142/129159/129166/4161566/index.html']
['/guangzhou/129142/129159/129166/4159365/index.html']
['/guangzhou/129142/129159/129166/4158449/index.html']
['/guangzhou/129142/129159/129166/4158442/index.html']
['/guangzhou/129142/129159/129166/4158436/index.html']
['/guangzhou/129142/129159/129166/4158431/index.html']
['/guangzhou/129142/129159/129166/4158426/index.html']
['/guangzhou/129142/129159/129166/4158414/index.html']
['/guangzhou/129142/129159/129166/4155532/index.html']

进入第二层网页,同样用正值表达式,两次筛选后,得到了每一条行政处罚信息公示表的下载链接地址,添加共同部分生成完整的链接地址。
file_spider.py的代码:

from scrapy import Request
from scrapy.spiders import Spider#导入Spider类
from seaborn_file_download.items import SeabornFileDownloadItem#导入Item
from selenium import webdriver
import chardet
import io,os
import time,re
import requests
import random

class FileDownloadSpider(Spider):
    #定义爬虫名称
    name = 'file'    
    def start_requests(self):
        url = "http://guangzhou.pbc.gov.cn/guangzhou/129142/129159/129166/index.html"
        yield Request(url)

    # 解析函数-获取第一页列表中每份处罚书的url地址
    def parse(self, response):
        IEdriver = "C:\Program Files\internet explorer\IEDriverServer.exe"
        browser = webdriver.Ie(IEdriver)
        browser.get('http://guangzhou.pbc.gov.cn/guangzhou/129142/129159/129166/index.html')
        titles = re.findall(r'font class="hei12">(.*?)</a></font>',browser.page_source)
        urls = []
        for title in titles:
            url = re.findall(r'href=\"(.*?)\" target="_blank">',title)
            urls.append(url[0])
     
        #遍历每每份处罚书的url
        for i in range(len(urls)):
            # 构建完整的url绝对地址
            url_next = 'http://guangzhou.pbc.gov.cn'+urls[i]
            print(url_next)
            browser.get(url_next)#根据第一页生成的链接地址,获取第二页信息
            #print(browser.page_source)
            text = re.findall(r'td align="left" class="hei14jj"><p>(.*?)</a></p></td>',browser.page_source)#从第二页信息中提取每一条处罚书的链接和名称 
            url_next2 = re.findall(r'a href=\"(.*?)\">',text[0])#提取每一条处罚书的链接
            url_down = 'http://guangzhou.pbc.gov.cn'+url_next2[0]#加上网站的链接头,构成完整的处罚书下载链接
            
            #创建SeabornFileDownloadItem对象
            item = SeabornFileDownloadItem()
            #将源文件的url地址以列表的形式保存到key为file_urls的Item中
            item["file_urls"] = [url_down]
            yield item

settings部分的代码:

BOT_NAME = 'seaborn_file_download'
SPIDER_MODULES = ['seaborn_file_download.spiders']
NEWSPIDER_MODULE = 'seaborn_file_download.spiders'
#FEED_EXPORT_ENCODING = 'utf-8-sig'
FEED_EXPORT_ENCODING = 'gbk'
#设置用户代理USER_AGENT
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66'
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
DOWNLOAD_DELAY = 3
ITEM_PIPELINES = {  'seaborn_file_download.pipelines.SaveFilePipeline': 300,
}

items部分的代码:

import scrapy
class SeabornFileDownloadItem(scrapy.Item):
    file_urls = scrapy.Field()#文件url地址
    files = scrapy.Field()#文件下载信息

pipelines.py部分的代码:

class SeabornFileDownloadPipeline(object):
    def process_item(self, item, spider):
        return item

from scrapy.pipelines.files import FilesPipeline#导入文件管道类
from scrapy import Request
#定义新的文件管道,继承于FilesPipeline
class SaveFilePipeline(FilesPipeline):
    # #构造并返回下载Request请求
    #def get_media_requests(self, item, info):
    #     # 获取文件url,构造文件下载Request请求
    #     yield  Request(url = item["file_urls"][0])
    # #文件下载(或下载失败)后调用该方法
    # def item_completed(self, results, item, info):#判断是否正确下载
    #     if not results[0][0]:
    #         raise DropItem("文件下载失败")
    #     #打印日志
    #     logger.debug("文件下载成功")
    #
    #     return item

    #设定文件名称,并返回
    def file_path(self, request, response=None, info=None):
        #获取文件名,并返回
        return request.url.split("/")[-1]

第三坑:详情页的链接地址,每个地址打开一个新的网页,只有一条行政处罚信息公示表名称,点击行政处罚信息公示表名称可以下载一个文档。可是,不同城市发布的行政处罚信息公示表的文件类型不统一,居然包括了xls,doc,DOC,et,ET四种,即使是同一xls,打开来看,表头格式也不一定相同,给后期的数据合并,统计分析增加了更多的麻烦。
同样用正值表达式,两次筛选后,得到了每一条行政处罚信息公示表的链接地址,scrapy成功批量下载了行政处罚信息公示表的文档(只是先爬网站第一页共10条记录,第二页及后面的等数据正常后再添加)。
心中暗喜,那只是一会儿。打开下载到的文档,乱码,心将崩溃。
在这里插入图片描述

走过路过的各位大神,指点一下迷津,不胜感激。祝各位大神新春快乐!工作顺利!

2021-02-17 11:12:41 [scrapy.core.engine] INFO: Closing spider (finished)
2021-02-17 11:12:41 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 6244,
 'downloader/request_count': 11,
 'downloader/request_method_count/GET': 11,
 'downloader/response_bytes': 59496,
 'downloader/response_count': 11,
 'downloader/response_status_count/200': 11,
 'elapsed_time_seconds': 35.240309,
 'file_count': 10,
 'file_status_count/downloaded': 10,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2021, 2, 17, 3, 12, 41, 375626),
 'item_scraped_count': 10,
 'log_count/DEBUG': 123,
 'log_count/INFO': 10,
 'log_count/WARNING': 1,
 'response_received_count': 11,
 'scheduler/dequeued': 1,
 'scheduler/dequeued/memory': 1,
 'scheduler/enqueued': 1,
 'scheduler/enqueued/memory': 1,
 'start_time': datetime.datetime(2021, 2, 17, 3, 12, 6, 135317)}
2021-02-17 11:12:41 [scrapy.core.engine] INFO: Spider closed (finished)

第一页获取的10份处罚通知书

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值