美文网首页
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