美文网首页
scrapy + selenium 爬取学院教师资料

scrapy + selenium 爬取学院教师资料

作者: EZ | 来源:发表于2020-05-22 21:35 被阅读0次

    要是直接访问iframe html url 就应该不用设置slenium中间件了,网页源代码有相关信息。明天看一下

    goal 学scrapy 发送 post请求。要学的太多啦趴

    1.spider文件
    issue1:资料信息可能借助js加载,scrapy不能爬取到
    solution: 在 middlewares.py 新建 SeleniumDownloadMiddleware类,使用slenium当作下载中间件,不过这种情况是模拟浏览器访问,网上有文章说可以借助其他模块操作。
    issue2: 资料信息储存在iframe中,直接访问ifame所在页面获取不到infram信息
    solution: 本次直接将iframe url 当作起始url ,或者将webdriver 对象swith_to到目标 iframe(未测试当前项目),不过使用 测试网页是可以

    知识点:if else 居然可以写到一行,果然需要学的还很多

    # -*- coding: utf-8 -*-
    import scrapy
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    from lxy.items import LxyItem
    
    class LxyspiderSpider(CrawlSpider):
        name = 'lxyspider'
        allowed_domains = ['domain']
        #start_urls = ['url'] #  教师信息在inframe里,需要switch_to iframe
        start_urls = ['inframe']  #直接访问 iframe
         #href="ShowJs.asp?id=266&xb="
        rules = (
            Rule(LinkExtractor(allow=r".*ShowJs.asp.+"),
                 callback='parse_js',
                 follow=False),)
        print("rule ok")
        def parse_js(self, response):
            name = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[1]/td[3]/text()').get()
            name = name if name else "无" #判断是否为空 m没有判断字符串为 “无”
            xibp = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[1]/td[5]/text()').get()
            xibp = xibp if xibp else "无"
            viwu = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[2]/td[2]/text()').get()
            viwu = viwu if viwu else "无"
            lwbp = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[2]/td[4]/text()').get()
            lwbp = lwbp if lwbp else "无"
            xtli = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[3]/td[2]/text()').get()
            xtli = xtli if xtli else "无"
            xtww = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[3]/td[4]/text()').get()
            xtww = xtww if xtww else "无"
            dmhx = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[4]/td[2]/text()').get()
            dmhx = dmhx if dmhx else "无"
            yzxl = response.xpath('/html/body/table/tbody/tr/td/table[1]/tbody/tr[4]/td[4]/text()').get()
            yzxl = yzxl if yzxl else "无"
            item = LxyItem(
            name = name,
            xibp = xibp,
            viwu = viwu,
            lwbp = lwbp,
            xtli = xtli,
            xtww = xtww,
            dmhx = dmhx,
            yzxl = yzxl)
    
            yield item
    
    1. middlewares配置
      主要是定义seleniume 下载中间件,下载中间件也可以配置user_agent 选择 与ip 代理
      isuue1 : 资料中含有电话的爬取不到,报错“Object of type Selector is not JSON serializable”
      solution : 没有跟 get()
    from scrapy import signals
    import random
    from selenium import webdriver
    import time
    
    from scrapy.http.response.html import HtmlResponse
    
    
    
    class SeleniumDownloadMiddleware(object):
        def __init__(self):
            self.driver = webdriver.Chrome(
                executable_path=r"D:\Anaconda\Scripts\chromedriver.exe"
            )
    
        def process_request(self,request,spider):
            self.driver.get(request.url)
            time.sleep(1)
            source = self.driver.page_source
            #包装成response 对象
            response = HtmlResponse(url=self.driver.current_url,
                                    body=source,
                                    request=request,
                                    encoding='utf-8'
            )
            print("response will be returned")
            #print(response.body.decode())
            return  response  #返回response给spider
    
    1. pipelines 文件
      将信息储存为json文件
    from scrapy.exporters import JsonLinesItemExporter
    class LxyPipeline:
        def __init__(self):
            self.fp = open("lxyju.json","wb")
            self.exporter = JsonLinesItemExporter(self.fp,
                                                  ensure_ascii=False,
                                                  encoding='utf-8')
        def open_spider(self,spider):
            print("="*6,"start","="*6)
            pass
    
        def process_item(self, item, spider):
            self.exporter.export_item(item)
            return item
    
        def close_spider(self,spider):
            self.fp.close()
    
    

    4.setting配置

    主要配置 下载延迟,user-agent ,开启 pipelines, 开启 middlewares
    
    

    5.使用json 模块 读取 json文件,
    issue: load好像不能读取很多行

    读取文件,for 循环反序列化字符串,
    Counter 可以计算list 频数,看到农学博士 农学硕士 理学博士人数较多
    Counter({'PhD in Ecology': 1,
             '博士(PhD)': 1,
             '农学博士': 67,
             '理学博士': 17,
             '博士': 7,
             '农学副博士': 1,
             '工学博士': 2,
             '农学硕士': 11,
             '哲学博士(森林生态学专业)': 1,
             '学士': 1,
             '无': 5,
             '理学硕士': 2,
             '理学学士': 1,
             '哲学博士': 2,
             '植物营养学 博士': 1,
             '文学硕士': 1,
             '工学硕士': 1,
             '教育学硕士': 1})
    
    

    不使用selenium

    issue: 可以爬取到 page source 但是没有返回关键信息,为None
    solution: 应该是xpath 路径的问题,使用原先的full xpath 得不到内容。使用相对路径可以获取到内容,将response对象转换成html文件,full path 也是没有变化。 不确定什么原因。
    不使用selenium 是很快,

    相关文章

      网友评论

          本文标题:scrapy + selenium 爬取学院教师资料

          本文链接:https://www.haomeiwen.com/subject/qegqahtx.html